programming: the action or process of writing computer programs. | rants: speak or shout at length in a wild, [im]passioned way.
2023-06-14
Simple Websocket Echo Benchmark
go 1.20.5 nbio 1.3.16
rps: 19157.16 avg/max latency = 1.66ms/319.88ms elapsed 10.2s
102 MB 0.6 core usage
rps: 187728.05 avg/max latency = 0.76ms/167.76ms elapsed 10.2s
104 MB 5 core usage
rps: 501232.80 avg/max latency = 12.48ms/395.01ms elapsed 10.1s
rps: 498869.28 avg/max latency = 12.67ms/425.04ms elapsed 10.1s
134 MB 15 core usage
bun 0.6.9
rps: 17420.17 avg/max latency = 5.57ms/257.61ms elapsed 10.1s
48 MB 0.2 core usage
rps: 95992.29 avg/max latency = 29.93ms/242.74ms elapsed 10.4s
rps: 123589.91 avg/max latency = 40.67ms/366.15ms elapsed 10.2s
rps: 123171.42 avg/max latency = 62.74ms/293.29ms elapsed 10.1s
55 MB 1 core usage
node 18.16.0
rps: 18946.51 avg/max latency = 6.64ms/229.28ms elapsed 10.3s
59 MB 0.2 core usage
rps: 97032.08 avg/max latency = 44.06ms/196.41ms elapsed 11.1s
rps: 114449.91 avg/max latency = 72.62ms/295.33ms elapsed 10.3s
rps: 109512.05 avg/max latency = 79.27ms/226.03ms elapsed 10.2s
59 MB 1 core usage
First line until 4th line are with 1s, 100ms, 10ms, 1ms delay before next request. Since Golang/nbio is by default can utilize multi-core so can handle ~50 rps per client, while Bun/Nodejs 11-12 rps per client. If you found a bug, or want to contribute another language (or create better client, just create a pull request on the github link above.
2022-04-05
Start/restart Golang or any other binary program automatically on boot/crash
There are some alternative to make program start on boot on Linux, the usual way is using:
1. SystemD, it could ensure that dependency started before your service, also could limit your CPU/RAM usage. Generate a template using this website or use kardianos/service
2. PM2 (requires NodeJS), or PMG
3. docker-compose (requires docker, but you can skip the build part, just copy the binary directly on Dockerfile command (that can be deployed using rsync), just set restart property on docker-compose and it would restart when computer boot), -- bad part, you cannot limit cpu/ram unless using docker swarm. But you can use docker directly to limit and use --restart flag.
3. lxc/lxd or multipass or other vm/lightweight vm (but still need systemd inside it XD at least it won't ruin your host), you can rsync directly to the container to redeploy, for example using overseer or tableflip, you must add reverse proxy or nat or proper routing/ip forwarding tho if you want it to be accessed from outside
4. supervisord (python) or ochinchina/supervisord (golang) tutorial here
5. create one daemon manager with systemd/docker-compose, then spawn the other services using goproc or pioz/god
6. monit it can monitor and ensure a program started/not dead
7. nomad (actually this one is deployment tool), but i can also manage workload
8. kubernetes XD overkill
9. immortal.run a supervisor, this one actually using systemd
10. other containerization/VM workload orchestrator/manager that usually already provided by the hoster/PaaS provider (Amazon ECS/Beanstalk/Fargate, Google AppEngine, Heroku, Jelastic, etc)
This is the systemd script that I usually use (you need to create user named "web" and install "unbuffer"):
$ cat /usr/lib/systemd/system/xxx.service
[Unit]
Description=xxx
After=network-online.target postgresql.service
Wants=network-online.target
[Service]
Type=simple
Restart=on-failure
User=web
Group=users
WorkingDirectory=/home/web/xxx
ExecStart=/home/web/xxx/run_production.sh
ExecStop=/usr/bin/killall xxx
LimitNOFILE=2097152
LimitNPROC=65536
ProtectSystem=full
NoNewPrivileges=true
[Install]
WantedBy=multi-user.target
$ cat /home/web/xxx/run_production.sh
#!/usr/bin/env bash
mkdir -p `pwd`/logs
ofile=`pwd`/logs/access_`date +%F_%H%M%S`.log
echo Logging into: $ofile
unbuffer time ./xxx | tee $ofile
2021-12-31
String Associative Array and CombSort Benchmark 2021 Edition
Last year, we've done string associative benchmark and lesser string associative benchmark (measuring string concat operation and built-in associative array set and get), numeric comb sort benchmark and string comb sort benchmark (measuring
basic array random access, string conversion, and array swap for number
and string), this year's using newer server: 32-core
running on 64-bit Ubuntu 21.10. This time we will skip programming languages that are no deb packages (unless the install script is just one line and doesn't ruin system directories) or no direct compile-run command like previous one, also only best of 3 runs.
$ alias time='/usr/bin/time -f "\nCPU: %Us\tReal: %es\tRAM: %MKB"
This time, NodeJS failed to complete (after waiting for an hour) with 10x more data compared to last year for assoc benchmark. Here's the spreadsheet and final result (Real duration and RAM):
Language | Command Flags | Version | Assoc | RAM | Num Comb | RAM | Str Comb | RAM | Total | RAM |
Go | go run | go1.17.5 | 12.39 | 2,305,824 | 0.46 | 83,096 | 3.33 | 245,896 | 16.18 | 2,634,816 |
Java | java | 18-ea+15-Ubuntu-4 | 10.70 | 5,582,308 | 0.96 | 170,240 | 6.93 | 722,152 | 18.59 | 6,474,700 |
Nim | nim r -d:release --gc:arc | 1.4.2 | 17.90 | 4,200,212 | 1.21 | 79,444 | 5.45 | 633,816 | 24.56 | 4,913,472 |
Python | pypy | 7.3.5 | 19.70 | 3,104,440 | 2.17 | 140,124 | 5.73 | 523,264 | 27.60 | 3,767,828 |
C | tcc -run | 0.9.27 | 22.68 | 2,820,568 | 1.01 | 80,484 | 4.80 | 392,896 | 28.49 | 3,293,948 |
Julia | julia | 1.6.5 | 23.98 | 3,714,448 | 0.52 | 255,844 | 4.60 | 861,076 | 29.10 | 4,831,368 |
V | v -prod run | 0.2.4 a0a1807 | 20.36 | 8,910,856 | 2.67 | 124,248 | 6.48 | 470,136 | 29.51 | 9,505,240 |
Lua | luajit | 2.1.0-beta3 | 16.70 | 1,133,876 | 3.27 | 133,504 | 10.80 | 511,468 | 30.77 | 1,778,848 |
Dart | dart | 2.15.1 | 25.92 | 2,101,152 | 1.40 | 208,056 | 5.75 | 574,852 | 33.07 | 2,884,060 |
Crystal | crystal run --release | 1.2.2 | 13.77 | 2,371,320 | 7.73 | 202,552 | 12.08 | 440,748 | 33.58 | 3,014,620 |
Nim | nim r -d:release | 1.4.2 | 24.92 | 3,864,100 | 1.76 | 79,548 | 7.51 | 1,211,200 | 34.19 | 5,154,848 |
PHP | php | 8.0.8 | 9.94 | 1,368,808 | 7.74 | 328,344 | 24.84 | 641,448 | 42.52 | 2,338,600 |
Crystal | crystal run | 0.35.1 | 38.85 | 2,372,004 | 9.97 | 179,176 | 22.27 | 441,720 | 71.09 | 2,992,900 |
V | v run | 0.2.4 a0a1807 | 51.81 | 8,911,004 | 6.63 | 79,716 | 18.43 | 470,420 | 76.87 | 9,461,140 |
Python | python3 | 3.9.7 | 43.11 | 4,106,892 | 29.16 | 405,332 | 43.08 | 722,996 | 115.35 | 5,235,220 |
Nim | nim r | 1.4.2 | 88.05 | 3,864,048 | 2.93 | 79,536 | 32.60 | 1,211,260 | 123.58 | 5,154,844 |
Ruby | ruby | ruby 2.7.4p191 | 52.48 | 2,970,908 | 27.15 | 100,320 | 52.23 | 708,940 | 131.86 | 3,780,168 |
Javascript | node | v16.13.1 | 999.99 | 9,999,999 | 0.71 | 115,044 | 6.11 | 461,836 | 1006.81 | 10,576,879 |
FAQ
Contributors: ilmanzo (Nim, Crystal, D), inkydragon (Julia)
2020-12-22
String Associative Array and CombSort Benchmark 2020 Edition
Language | Command Flags | Version | Assoc | RAM | Num Comb | RAM | Str Comb | RAM | Total | RAM |
Go | go run | 1.14.7 | 1.56 | 257,440 | 0.73 | 82,844 | 4.74 | 245,432 | 7.03 | 585,716 |
Go | go run | 1.15.6 | 1.73 | 256,620 | 0.78 | 82,896 | 4.86 | 245,468 | 7.37 | 584,984 |
Nim | nim r -d:release --gc:arc | 1.4.2 | 1.56 | 265,172 | 0.79 | 79,284 | 5.77 | 633,676 | 8.12 | 978,132 |
Nim | nim r -d:release --gc:orc | 1.4.2 | 1.53 | 265,160 | 0.94 | 79,380 | 5.83 | 633,636 | 8.30 | 978,176 |
Javascript | node | 14.15.2 | 2.21 | 327,048 | 0.87 | 111,972 | 6.13 | 351,520 | 9.21 | 790,540 |
Crystal | crystal run --release | 0.35.1 | 1.81 | 283,648 | 1.44 | 146,700 | 6.09 | 440,796 | 9.34 | 871,144 |
Javascript | ~/.esvu/bin/v8 | 8.9.201 | 1.77 | 177,748 | 0.89 | 105,416 | 6.71 | 335,236 | 9.37 | 618,400 |
C | tcc -run | 0.9.27 | 2.61 | 291,912 | 1.45 | 80,832 | 6.40 | 393,352 | 10.46 | 766,096 |
Java | java | 14.0.2 2020-07-14 | 1.63 | 545,412 | 1.50 | 165,864 | 7.69 | 743,572 | 10.82 | 1,454,848 |
Nim | nim r -d:release | 1.4.2 | 1.91 | 247,456 | 0.96 | 79,476 | 8.38 | 1,211,116 | 11.25 | 1,538,048 |
Dart | dart | 2.10.4 | 2.91 | 385,496 | 1.61 | 191,916 | 7.31 | 616,716 | 11.83 | 1,194,128 |
Python | pypy | 7.3.1+dfsg-2 | 2.19 | 331,776 | 2.83 | 139,740 | 8.04 | 522,648 | 13.06 | 994,164 |
Javascript | ~/.esvu/bin/chakra | 1.11.24.0 | 2.73 | 487,400 | 1.27 | 102,192 | 11.27 | 803,168 | 15.27 | 1,392,760 |
Javascript | ~/.esvu/bin/jsc | 271117 | 5.90 | 593,624 | 0.68 | 111,972 | 9.09 | 596,088 | 15.67 | 1,301,684 |
V | v -prod run | 0.2 32091dd gcc-10.2 | 4.78 | 1,469,932 | 1.86 | 79,376 | 14.06 | 1,560,516 | 20.70 | 3,109,824 |
Lua | luajit | 2.1.0-beta3 | 4.11 | 250,828 | 3.76 | 133,424 | 12.91 | 511,196 | 20.78 | 895,448 |
Javascript | ~/.esvu/bin/sm | JavaScript-C86.0a1 | 5.61 | 378,064 | 1.40 | 96,480 | 13.81 | 393,376 | 20.82 | 867,920 |
V | v -prod run | 0.2 32091dd gcc-9.3 | 5.05 | 1,469,936 | 2.14 | 79,408 | 14.62 | 1,560,484 | 21.81 | 3,109,828 |
Javascript | ~/.esvu/bin/graaljs | CE Native 20.3.0 | 7.78 | 958,380 | 4.45 | 405,900 | 14.31 | 911,220 | 26.54 | 2,275,500 |
Go | gopherjs run | 1.12-3 (node 14.15.2) | 11.76 | 594,896 | 2.04 | 119,604 | 18.46 | 397,396 | 32.26 | 1,111,896 |
Nim | nim r | 1.4.2 | 6.60 | 247,444 | 3.05 | 79,332 | 31.85 | 1,211,208 | 41.50 | 1,537,984 |
PHP | php | 7.4.3 | 1.34 | 190,644 | 10.11 | 328,452 | 34.51 | 641,664 | 45.96 | 1,160,760 |
Ruby | truffleruby | 21.1.0-dev-c1517c55 | 14.54 | 2,456,156 | 3.09 | 453,152 | 29.27 | 3,660,284 | 46.90 | 6,569,592 |
Crystal | crystal run | 0.35.1 | 5.69 | 284,328 | 12.00 | 153,828 | 31.69 | 441,740 | 49.38 | 879,896 |
Javascript | ~/.esvu/bin/quickjs | 2020-11-08 | 3.90 | 252,484 | 23.48 | 80,772 | 34.80 | 471,624 | 62.18 | 804,880 |
V | v run | 0.2 36dcace gcc-9.3 | 5.28 | 1,470,668 | 6.60 | 80,232 | 58.99 | 1,561,176 | 70.87 | 3,112,076 |
Lua | lua | 5.3.3 | 5.98 | 366,516 | 27.26 | 264,648 | 46.05 | 864,300 | 79.29 | 1,495,464 |
Ruby | ruby | 2.7.0p0 | 6.31 | 371,456 | 19.29 | 100,536 | 58.82 | 694,560 | 84.42 | 1,166,552 |
Python | python3 | 3.8.5 | 5.47 | 314,564 | 33.96 | 404,976 | 47.79 | 722,820 | 87.22 | 1,442,360 |
Ruby | jruby | 9.2.9.0 | 7.45 | 1,878,184 | 34.11 | 1,976,844 | 59.83 | 7,115,448 | 101.39 | 10,970,476 |
Ruby | ruby | 3.0.0p0 | 5.94 | 371,832 | 24.87 | 92,844 | 74.32 | 1,015,096 | 105.13 | 1,479,772 |
Go | tinygo run | 0.16.0 | 999.99 | 318,148 | 3.68 | 300,548 | 252.34 | 711,340 | 1256.01 | 1,330,036 |
Contributors: ilmanzo (Nim, Crystal, D)