How to install nvm

This is a follow up to [How to install npm the right way]. It turns out that while convenient for Node development, nvm is notoriously slow. Thanks to reddit user sscotth we can solve that quite easily.

First, install nvm normally

curl -o- | bash

Then find the lines nvm added to your .rc file (bashrc or zshrc), delete that shit

# export NVM_DIR="$HOME/.nvm"
# [ -s "$NVM_DIR/" ] && \. "$NVM_DIR/"  # This loads nvm
# [ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion"  # This loads nvm bash_completion

Next, add this to your .rc file

declare -a NODE_GLOBALS=(`find ~/.nvm/versions/node -maxdepth 3 -type l -wholename '*/bin/*' | xargs -n1 basename | sort | uniq`)


load_nvm () {
    export NVM_DIR=~/.nvm
    [ -s "$NVM_DIR/" ] && . "$NVM_DIR/"

for cmd in "${NODE_GLOBALS[@]}"; do
    eval "${cmd}(){ unset -f ${NODE_GLOBALS}; load_nvm; ${cmd} \$@ }"

Your globally installed programs like create-react-app will still use the current version of node, while it only loads once and not boggle down your terminal startup everytime.


Gõ tiếng Việt trên Ubuntu

Cách gõ Dvorak trên Ubuntu với ibus-unikey

Các bộ gõ tiếng Việt trên ubuntu

  • ibus-unikey là bộ gõ có sẵn trong source, dễ cài nhất nhưng có vấn đề bị revert keyboard như ở trên
  • ibus-teni (telex-vni) mới hơn
  • ibus-bamboo: cùng tiêu chí với teni, bộ gõ mới nhất, được cập nhật thường xuyên, hỗ trợ nhiều chế độ gõ cho nhiều ứng dụng khác nhau, tuy nhiên chưa được nổi tiếng như ibus-unikey vì hầu hết các tài liệu hướng dẫn đều viết về ibus-unikey (có lẽ vì unikey namesake quá nổi tiếng trên Windows)

Install IP Time USB Wifi Adapter driver for Ubuntu Linux

It’s not that hard… provided you know where to look.

First, find out the model ID by going


You’ll get something like this, where “Realtek” is the chip manufacturer, which is usually the case for IPTime

Next, google the ID, it will take you to stack overflow, in my case, this answer

Which leads me to this repository

A few commands later…

cd rtl88x2BU_WiFi_linux_v5.3.1_27678.20180430_COEX20180427-5959
VER=$(sed -n 's/\PACKAGE_VERSION="\(.*\)"/\1/p' dkms.conf)
sudo rsync -rvhP ./ /usr/src/rtl88x2bu-${VER}
sudo dkms add -m rtl88x2bu -v ${VER}
sudo dkms build -m rtl88x2bu -v ${VER}
sudo dkms install -m rtl88x2bu -v ${VER}
sudo modprobe 88x2bu

And voila, it works even without a reboot

How to type in Dvorak but keep Qwerty shortcuts

Every Dvorak user knows the pain: shortcuts in every program on earth is designed with Qwerty in mind. Cut – Copy – Paste is supposed to be next to each other but it’s not so in Dvorak.

As A Dvorak user, I’ve had to find and try many solutions for this problem over the years. It involved all sort of hacks and modifications to the deepest parts of the operating system: creating custom keyboard layouts, modifying the registry, write a new input method etc. Even so, it didn’t work in some applications (looking at you, IntelliJ, Java and Firefox – the bugs isn’t even fixed yet, and they are almost 10 years old!).

Almost 10 years later, in 2019, I finally found solutions that work for all major operating systems, and here they are:


Apple makes great software, even though I don’t like their business practices, that’s an undeniable fact. MacOS is the simplest of the three OSes: Simply add Dvorak-QWERTY as an input method and you are good to go!


Used to be the second-easiest OS to work with, but recently Microsoft started cracking down on custom software and drivers so any custom keyboard layout not provided by them will get wiped out (and basically becomes very buggy with Windows 8 and up).

My solution? Use AutoHotKey! Yes, it’s an extra install, but it works reliably across all machines I’ve used with little setup required.

How to use Dvorak-QWERTY with AutoHotKey on Windows

  1. Install and set a Dvorak layout as your default (which language doesn’t matter)
  2. Install AutoHotKey
  3. Save this gist to your machine
  4. Optional: Convert the .ahk file to .exe with AutoHotKey so you can use it elsewhere without AHK
  5. Put the .ahk file in your startup folder
  6. Profit!

Notes about the AHK script

  • It will switch the layout to Qwerty when control keys or a combination of them is pressed (Ctrl, Alt, Win, Ctrl + Alt, Ctrl + Win)
  • It will disable itself when the input language is Korean (code = 68289554) so you can type Korean characters uninterfered. You can find similar code for Japanese, Chinese, etc. using AHK’s inspection tool
  • It will disable itself when scroll lock is on. This is for exceptional cases when you want to use Qwerty without pressing modifiers key
  • If you need additional combination of control keys, you must copy a whole section and add the control keys manually. For some reason, AHK’s * doesn’t work properly with control keys no there’s no way to make the script shorter


What worked for me: modifying the xkb keymaps! This idea came when I tried to replicate the AutoHotKey solution on Linux. I found source code of past projects that tried to achieve this. Sadly no step by step guide on how to apply them. Here’s how:

  • Press the plus button
  • Choose English (United States)
  • Choose any of the English (Dvorak-Qwerty), the flavor you prefer
  • Now switch the keyboard layout to your newly added layout
  • You’re done!


Dvorak is a good ergonomic layout but it hasn’t seen more widespread adoption due to entry barriers like the QWERTY shortcut problem. I hope this post solved part of that problem.

Benchmark Flatbuffer / Protobuffer / C++ Struct performance

I’m building a project that requires maximal performance. But it also uses many data structure that need some flexibility. Naturally Flatbuffer and Protobuffer are potential candidates. So I did some benchmark. Here’s the result

Serialization / de-serialization

Raw structs bench start...
total = 15860948312882282624
Raw structs bench: 312 wire size, 210 compressed wire size
* 0.049046 encode time, 0.003316 decode time
* 0.067384 use time, 0.003062 dealloc time
* 0.073762 decode/use/dealloc
FlatBuffers bench start...
total = 15860948312882282624
FlatBuffers bench: 344 wire size, 220 compressed wire size
* 2.920470 encode time, 0.003350 decode time
* 0.740325 use time, 0.003186 dealloc time
* 0.746861 decode/use/dealloc
Protocol Buffers LITE bench start...
total = 15860948312882282624
Protocol Buffers LITE bench: 228 wire size, 174 compressed wire size
* 3.268726 encode time, 3.188535 decode time
* 0.200258 use time, 0.399030 dealloc time
* 3.787823 decode/use/dealloc

Include network communication

FLATBUF bench start...
total bytes = 15898507595776707224
* 0.003065 create time
* 0.238328 receive time
* 0.002950 use
* 0.000782 free
* 0.245125 total time
PROTOBUF bench start...
total bytes = 0
* 0.000766 create time
* 0.244944 receive time
* 0.001007 use
* 0.000785 free
* 0.247503 total time
RAW bench start...
total bytes = 54377074000
* 0.001709 create time
* 0.002417 receive time
* 0.000813 use
* 0.000759 free
* 0.005699 total time

The conclusion

  • While flatbuffer / protobuffer provides a convenient API to define data structures, have them dynamically expanded and support a variety of languages, they are slower than just using raw structures
  • While flatbuffer is faster than protobuffer at pure serialization / deserialization, the difference is minimal when accounting for remote RPC costs
  • We need to test more recent libraries for serialization, and potentially combine them with the custom RPC model we are having with EVPP: YAS, cap’n’proto

The journey

It grinds my gears when code doesn’t work
  • Contrary to popular belief, Google’s code does not always work
  • The gRPC example in flatbuffer is outdated and is not working
  • The benchmark that proves flatbuffer is faster than protobuf is from 2016 and no longer compiles with the latest libraries

I fixed the above problems in

  • The latest flatbuffer no longer work recent versions of gRPC due to some abstractions in data structure
  • I need to modify gRPC to expose legacy data structures that flatbuffer needs access to. Thus this repository is born
  • I need to merge some recent contributions that solve the problem but did not confirm to Google’s code standard in order to make flatbuffer work

Finally, I need to write benchmark code for all three (Flatbuffer + gRPC, Protobuf + gRPC, raw struct + EVPP). The complete code is available here

Tags you can use

  • v1.1: Serialization / deserialization only, runs on one machine
  • v2.0: Serialization + deserialization + network transmission, can be run on two machines

Note that if you have already installed another version of gRPC and/or protobuf, you need to remove them with

$ sudo rm -f /usr/local/bin/*grpc*
$ sudo rm -f /usr/local/bin/protoc
$ sudo rm -f /usr/local/lib/*gpr*
$ sudo rm -f /usr/local/lib/*grpc*
$ sudo rm -f /usr/local/lib/*protobuf*
$ sudo rm -f /usr/local/lib/*protoc*
$ sudo rm -f /usr/local/lib/pkgconfig/*gpr*
$ sudo rm -f /usr/local/lib/pkgconfig/*grpc*
$ sudo rm -f /usr/local/lib/pkgconfig/*protobuf*
$ sudo rm -rf /usr/local/include/google
$ sudo rm -rf /usr/local/include/grpc
$ sudo rm -rf /usr/local/include/grpc++
$ sudo rm -rf /usr/local/include/grpcpp