How to Compile Go Code 40% Faster With RAM Disk
Go is already famous for its impressive compilation speed.
But if you came from a scripting language with practically no compile time, you're probably not satisfied.
Here's the compile time after running go build main.go
a few times to warm up the file system.
real 0m2.590s
user 0m2.685s
sys 0m0.775s
It's easily 2 to 3 times slower when the files aren't cached. Which could happen if your disk is experiencing a lot of usage. Here's the compile time when compiling from RAM disk. A whopping 40% faster; almost a second off.
real 0m1.871s
user 0m2.124s
sys 0m0.380s
Here's the bash script to get things working:
#!/bin/sh
if [ ! -d ~/ramdisk ]; then
mkdir ~/ramdisk
fi
sudo mount -t tmpfs -o size=512M tmpfs ~/ramdisk
rsync -ah ~/go ~/ramdisk/
rsync -ah --exclude '.git' ~/path/to/project ~/ramdisk
export GOPATH=$HOME/ramdisk/go
This creates a directory under the home folder as ~/ramdisk. Then assigns 512MB disk space and mounts it on the RAM. The rsync calls copy all Go files and project files to the RAM disk. Finally, it sets GOPATH to the new Go path under ~/ramdisk.
The next step is to reflect all file changes to the RAM disk instead of editing the files directly on it. This way you don't have to worry about losing your work. To do that we need a tool to watch for file changes and automatically duplicate the file. You can use any tool you like e.g. inotify, fswatch, nodemon etc. I'm going to use xnotify, a high level tool which can help with the build process.
./xnotify --verbose -i . --base /home/vagrant/ramdisk/project --batch 50 -- go build cmd/main.go -- ./main | xargs -L 1 ./copy.sh
copy.sh:
#!/bin/sh
NAME=$2
SRC=/path/to/project/$NAME
if [ -f $SRC ]; then
echo Copying: $NAME
cp $SRC ~/ramdisk/project/$NAME
fi
The command above basically copies the file to the RAM disk and runs go build cmd/main.go && ./main
when a file changes.
Now if we want to stop using the RAM disk we just need to run this script:
#!/bin/sh
sudo lsof -n ~/ramdisk
sudo umount ~/ramdisk
rm ~/ramdisk -r
export GOPATH=$HOME/go