2016-06-05

Solution for golang Slow Compile

I think this need more exposure, http://dev.pawelsz.eu/2015/09/slow-go-compilation.html show that slow compilation source, by using -x flag. This also related to my previous answer on stackoverflow http://stackoverflow.com/a/26752149/1620210 a real slowdown that happened after upgrading or downgrading to newer version of golang. Fortunately, there's a quickfix for that:

First of all if you are using go 1.7, you'll need to change the ownership of your GOROOT's pkg directory:

[ `ls -ld $GOROOT/pkg | awk '{print $3}'` != `whoami` ] && sudo chown -Rv `whoami` $GOROOT/pkg

Then if you are upgrading or downgrading, you'll need to remove the GOPATH's pkg directory, there's the bash snippet to check if gitlab.com/kokizzu/gokil library was precompiled with different golang version than installed:

PKG_OS_ARCH=`go version | cut -d ' ' -f 4 | tr '/' '_'`
[ `strings $GOPATH/pkg/$PKG_OS_ARCH/gitlab.com/kokizzu/gokil/A.a | grep 'go object' | head -n 1 | cut -f 5 -d ' '` != `go version | cut -f 3 -d ' '` ] && rm -rf $GOPATH/pkg

This last part stolen from the blog above, the real script that makes the next compile runs faster:

go list -f '{{.Deps}}' ./... | tr "[" " " | tr "]" " " | \
  xargs go list -f '{{if not .Standard}}{{.ImportPath}}{{end}}' | \
  xargs go install -a

Alternatively, you can use

go build -i

The last 2 commands above looks for all dependencies and recompile/preinstall them, it's better than I expected, normally it took about 15 seconds to recompile on go1.6.2.

# go 1.4.3
[gin] Build Successful in 1802.47 ms
[gin] Build Successful in 2854.65 ms
[gin] Build Successful in 2325.35 ms

# go 1.6.2
[gin] Build Successful in 5673.43 ms
[gin] Build Successful in 8081.75 ms
[gin] Build Successful in 6867.12 ms

# go 1.7b1
[gin] Build Successful in 2579.98 ms
[gin] Build Successful in 3649.08 ms
[gin] Build Successful in 4182.04 ms
[gin] Build Successful in 3881.66 ms
[gin] Build Successful in 3722.20 ms
[gin] Build Successful in 2785.84 ms
[gin] Build Successful in 2981.62 ms
[gin] Build Successful in 3793.66 ms
[gin] Build Successful in 4458.86 ms
[gin] Build Successful in 4376.60 ms

Anyway I still stick with go1.4.3 since it has the fastest compile, it makes our edit-compile-test cycle faster.

2016-05-26

Iris Web Framework

Shock! That was what I feel when see Iris benchmark '__'), after looking at the code, ah no wonder, it uses fastest router (fasthttp), that uses almost zero allocation per request.

These graphs stolen from SmallNest's go framework benchmark.









As usual, static request means nothing, dynamic request that uses database are the real bottleneck :3
Btw Iris has book for those who are interested. For those who doesn't need full framework, you can use the fasthttprouter.

EDIT: before you use Iris because of performance, see links on the comments below: this by julienschmidt (one that create httprouter) and this by dlsniper (one that initialize go-lang-idea-plugin project).

 What's the alternative? you can use valyala's FastHttp (only router), Arteugo, or Fiber (full framework, really similar to ExpressJS)

2016-04-19

Remap Keyboard Shortcut on Mac OSX

Recently I bought a secondhand Macbook Pro, since it's sold in a really-really good price. This is my first time experiencing Mac OSX, and my experience has been quite good, almost everything is there and easy as easy as yaourt+better automation (called brew), better UI than Windows, and I never feel any lag (maybe because it's SSD). All great, except, the shortcut keys, it's quite weird to have Fn key on the left of Ctrl key (just like most Lenovo laptops), also command key that replaces almost every normal shortcut on Windows and Linux.

First few days, using the shortcuts, I quite dissatisfied until I found about Karabiner! With that app, I could remap every keyboard shortcuts that I like so it becomes similar to Linux and Windows settings.


First thing I've done is switch Ctrl and Fn and vice versa. For all other shortcut, I edit the private.xml to match my preferred shortcut to Mac's shortcut. These are the content of the file:

<?xml version="1.0"?>
<root>
    <appdef>
        <appname>ITERM2</appname>
        <equal>com.googlecode.iterm2</equal>
    </appdef>
    <appdef>
        <appname>INTELLIJ</appname>
        <equal>com.jetbrains.intellij</equal>
    </appdef>
    <item>
        <name>Command-Q to Control-C</name>
        <appendix>Cmd-Q to Ctrl-C for iTerm2</appendix>
        <identifier>CQ2CC</identifier>
        <only>ITERM2</only>
        <autogen>
            __KeyToKey__
            KeyCode::Q, ModifierFlag::COMMAND_L,
            KeyCode::C, ModifierFlag::CONTROL_L
        </autogen>
    </item>
    <item>
        <name>Control to Alt</name>
        <appendix>Ctrl to Alt (Left/Right/Backspace)</appendix>
        <identifier>C2A</identifier>
        <not>INTELLIJ</not>
        <autogen>
            __KeyToKey__
            KeyCode::DELETE, ModifierFlag::CONTROL_L,
            KeyCode::DELETE, ModifierFlag::OPTION_L
        </autogen>
        <autogen>
            __KeyToKey__
            KeyCode::CURSOR_LEFT, ModifierFlag::CONTROL_L,
            KeyCode::CURSOR_LEFT, ModifierFlag::OPTION_L
        </autogen>
        <autogen>
            __KeyToKey__
            KeyCode::CURSOR_RIGHT, ModifierFlag::CONTROL_L,
            KeyCode::CURSOR_RIGHT, ModifierFlag::OPTION_L
        </autogen>
        <autogen>
            __KeyToKey__
            KeyCode::CURSOR_LEFT, ModifierFlag::CONTROL_L | ModifierFlag::SHIFT_L,
            KeyCode::CURSOR_LEFT, ModifierFlag::OPTION_L | ModifierFlag::SHIFT_L
        </autogen>
        <autogen>
            __KeyToKey__
            KeyCode::CURSOR_RIGHT, ModifierFlag::CONTROL_L | ModifierFlag::SHIFT_L,
            KeyCode::CURSOR_RIGHT, ModifierFlag::OPTION_L | ModifierFlag::SHIFT_L
        </autogen>
    </item>
    <item>
        <name>Control to Command</name>
        <appendix>Ctrl to Cmd (A/C/F/R/S/T/V/W/X/Z)</appendix>
        <identifier>C2C</identifier>
        <autogen>
            __KeyToKey__
            KeyCode::A, ModifierFlag::CONTROL_L,
            KeyCode::A, ModifierFlag::COMMAND_L
        </autogen>
        <autogen>
            __KeyToKey__
            KeyCode::C, ModifierFlag::CONTROL_L,
            KeyCode::C, ModifierFlag::COMMAND_L
        </autogen>
        <autogen>
            __KeyToKey__
            KeyCode::F, ModifierFlag::CONTROL_L,
            KeyCode::F, ModifierFlag::COMMAND_L
        </autogen>
        <autogen>
            __KeyToKey__
            KeyCode::L, ModifierFlag::CONTROL_L,
            KeyCode::L, ModifierFlag::COMMAND_L
        </autogen>
        <autogen>
            __KeyToKey__
            KeyCode::R, ModifierFlag::CONTROL_L,
            KeyCode::R, ModifierFlag::COMMAND_L
        </autogen>
        <autogen>
            __KeyToKey__
            KeyCode::S, ModifierFlag::CONTROL_L,
            KeyCode::S, ModifierFlag::COMMAND_L
        </autogen>
        <autogen>
            __KeyToKey__
            KeyCode::T, ModifierFlag::CONTROL_L,
            KeyCode::T, ModifierFlag::COMMAND_L
        </autogen>
        <autogen>
            __KeyToKey__
            KeyCode::V, ModifierFlag::CONTROL_L,
            KeyCode::V, ModifierFlag::COMMAND_L
        </autogen>
        <autogen>
            __KeyToKey__
            KeyCode::W, ModifierFlag::CONTROL_L,
            KeyCode::W, ModifierFlag::COMMAND_L
        </autogen>
        <autogen>
            __KeyToKey__
            KeyCode::X, ModifierFlag::CONTROL_L,
            KeyCode::X, ModifierFlag::COMMAND_L
        </autogen>
        <autogen>
            __KeyToKey__
            KeyCode::Z, ModifierFlag::CONTROL_L,
            KeyCode::Z, ModifierFlag::COMMAND_L
        </autogen>
    </item>
</root>

Keyboard map above will trigger most of mac shortcut, but using Ctrl key instead of Cmd key:

  • Cmd-Q will trigger Ctrl-C (exit current program) on iTerm2
  • Ctrl-Left/Right: skip word
  • Ctrl-Shift-Left/Right: select word
  • Ctrl-Backspace: delete 1 word
  • Ctrl-A: select all
  • Ctrl-C: copy
  • Ctrl-F: find
  • Ctrl-L: location
  • Ctrl-R: refresh
  • Ctrl-S: save
  • Ctrl-T: new tab
  • Ctrl-V: paste
  • Ctrl-W: close tab
  • Ctrl-X: cut
  • Ctrl-Z: undo
I didn't put some other shortcuts that I didn't use (mostly because it's can be configured on the IDE/TextEditor) or just because it's already works well, for example Ctrl-Tab for switching tab, Ctrl-D for logout, and so on. If you want to learn more, you can read the reference here.

2016-03-09

Lightweight Go IDE (with Debugging support)

Today I found that Visual Studio Code by Microsoft is quite charming, it based on Electron, library that being used to make Atom Editor (and Nuclide by Facebook). It loads fast, really fast. In ArchLinux or Manjaro, you can install it using this command:

yaourt -S visual-studio-code

After installing, type Ctrl+Shift+P, Install Extension, choose Go (Rich Go bla bla..). And yes, it requires internet connection.

Then install the tools required:

go get -u -v github.com/nsf/gocode
go get -u -v github.com/rogpeppe/godef
go get -u -v github.com/golang/lint/golint
go get -u -v github.com/lukehoban/go-find-references
go get -u -v github.com/lukehoban/go-outline
go get -u -v sourcegraph.com/sqs/goreturns
go get -u -v golang.org/x/tools/cmd/gorename
go get -u -v github.com/tpng/gopkgs
go get -u -v github.com/newhook/go-symbols

For debugging, install delve (it requires Go 1.5 or newer).

The import bulb will show if a package not yet imported:

The autocomplete just works as expected:

Argument tooltip (parameter info) shown correctly:

Jump to definition works (Ctrl+Click):

I believe this is better alternative (for now) than Atom, Brackets, LightTable, and LimeText (incomplete SublimeText implementation).