ApacheBenchで雑にNimとGolangを比べてみる

Nim という言語が Golang や Rust よりも軽いし早いぜ！！みたいな記事を見かけたので
楽しそうな Nim に乗り換えたいなぁ、でも仕事じゃfizzbuzzでもFibonacciも出てこないからなぁ
と思い `ab` を使って調べてみました。

やり方がまずいわボケ！みたいなツッコミ待ちで記事を書いたので、ガシガシ突っ込んでもらえると幸いです。

### 使用するリポジトリ

  - https://github.com/mijime/la-webapp-helloworld
    - Golang は http.Server, Nim は asynchttpserver はそのまま使ってる感じです
    - ベースのイメージは alpine にしました

#### 追記

  - コメントで指摘いただいたので、リリースビルドでベンチマーク取り直しました！
  - 2017/10/31 結果のスコアが平均とずれていたので、より近いものにしました

### 環境

* AMI: ami-785c491f

  - Ubuntu
  - VERSION="16.04.2 LTS (Xenial Xerus)"
  - Intel(R) Xeon(R) CPU E5-2676 v3 @ 2.40GHz
  - cpu cores       : 1

* Instance-Type: t2.micro

  - MemTotal:        1014660 kB

### 結果

| metrics/lang                                                  | Nim     | Golang  |
| :---                                                          | :---    | :---    |
| Requests per second  [#/sec]                                  | 6527.52 | 7341.14 |
| Time per request [ms]                                         | 15.320  | 13.622  |
| Time per request [ms] \(mean, across all concurrent requests) | 0.153   | 0.136   |
| Transfer rate [Kbytes/sec] received                           | 325.10  | 931.98  |

Transfer rate が大体3倍ぐらい差がある...


### 作業ログ

docker の setup

```bash
docker-machine create --driver amazonec2 --amazonec2-region ap-northeast-1 aws-default
eval "$(docker-machine env aws-default | tee ~/.dockerc)"
```

```bash
docker-machine ls aws-default
NAME          ACTIVE   DRIVER      STATE     URL                         SWARM   DOCKER        ERRORS
aws-default   *        amazonec2   Running   tcp://13.114.246.147:2376           v17.09.0-ce   
```

`docker stats` だと味気なかったので `google/cadvisor` を使って監視します

```bash
docker-compose build
docker-compose up -d cadvisor
```

cadvisor のポート開けておきます

```bash
aws ec2 describe-instances # security group id 調べる
aws ec2 authorize-security-group-ingress --group-id ${sgid} --port 8080 --cidr $(curl -sSL ifconfig.io)/32 --protocol tcp
```

まずは nim から...

```bash
docker-compose up -d nimapp
# 立ち上がったら、http://${dockerのIP}:8080/containers/docker の一番下をみる
docker-compose up nimapp-bench
```

なるほど. なるほど. (黄色が nimapp)
![スクリーンショット 2017-10-07 22.37.06.png](https://qiita-image-store.s3.amazonaws.com/0/92474/72f10e90-46ba-f2f9-8f9a-a258f60627d2.png)

```bash
docker-compose logs nimapp-bench
...
nimapp-bench_1  | Concurrency Level:      100
nimapp-bench_1  | Time taken for tests:   15.501 seconds
nimapp-bench_1  | Complete requests:      100000
nimapp-bench_1  | Failed requests:        0
nimapp-bench_1  | Total transferred:      5100000 bytes
nimapp-bench_1  | HTML transferred:       1200000 bytes
nimapp-bench_1  | Requests per second:    6451.14 [#/sec] (mean)
nimapp-bench_1  | Time per request:       15.501 [ms] (mean)
nimapp-bench_1  | Time per request:       0.155 [ms] (mean, across all concurrent requests)
nimapp-bench_1  | Transfer rate:          321.30 [Kbytes/sec] received
...
```

次に Golang を...

```bash
docker-compose stop nimapp
docker-compose up -d goapp
docker-compose up goapp-bench
```

なるほど. なるほど. なるほど. (青がgoapp)

![スクリーンショット 2017-10-07 11.22.36.png](https://qiita-image-store.s3.amazonaws.com/0/92474/05634422-eab1-402e-28e2-c17cca4aacd7.png)

```bash
docker-compose logs goapp-bench
...
goapp-bench_1   | Concurrency Level:      100
goapp-bench_1   | Time taken for tests:   14.371 seconds
goapp-bench_1   | Complete requests:      100000
goapp-bench_1   | Failed requests:        0
goapp-bench_1   | Total transferred:      13000000 bytes
goapp-bench_1   | HTML transferred:       1300000 bytes
goapp-bench_1   | Requests per second:    6958.52 [#/sec] (mean)
goapp-bench_1   | Time per request:       14.371 [ms] (mean)
goapp-bench_1   | Time per request:       0.144 [ms] (mean, across all concurrent requests)
goapp-bench_1   | Transfer rate:          883.41 [Kbytes/sec] received
...
```

... よくわからないので、並べて検証します

```bash
docker-compose stop goapp nimapp
docker system prune # 一旦掃除

docker-compose up -d goapp nimapp
docker-compose up goapp-bench
docker-compose up nimapp-bench
```

... なるほど? (赤 goapp, 黄 nimapp)

![スクリーンショット 2017-10-07 22.48.48.png](https://qiita-image-store.s3.amazonaws.com/0/92474/d988c62d-88da-b2de-0275-749928e6085a.png)

### 感想

- Nim は素人には難しそうです。。
- クロスコンパイルもちょっと手元のPCだけだと難しそう。。。
- ~~参考にしたページだと Golang と同じ rps でたとのことだったので、検証手順が間違っている可能性は大きいです~~ 間違ってました
- ~~同時接続数が 100 なのは 1000 ぐらい越えると nim 側が詰まりはじめるので
少なめに設定しています。~~ 普通に nim でも捌けました。しゅごい
  - 逆に golang とか netty とかが捌けるのはなんでなんだ

- ~~自分でベンチマークとるの重要~~ ちゃんとドキュメント読むの重要

### 参考

- http://wolfbash.hateblo.jp/entry/2017/09/27/172150