luvitを検証してみる(その1)


## 前書き

[luvit](https://luvit.io/) という Node.js ライクなプロジェクトを発見したので、検証してみたくなりました。その第1弾(第2弾は...)。

手始めに Hello World を返すだけの Http Sever を立て、ベンチマークしてみました。負荷試験ツールは手取り早くやりたかったので ApachBench を使いました。

しかし、途中から趣旨が変わります。

## luvit http(luajit)

### 実行環境
>21:11 $ luvit
Welcome to the Luvit repl!
>print(jit.version)
LuaJIT 2.1.0-beta2

### レスポンス
>HTTP/1.1 200 OK
Connection: keep-alive
Content-Length: 12
Content-Type: text/plain
Date: Thu, 27 Apr 2017 11:37:22 GMT
>
>Hello world

### 計測結果
```
18:31 $ ab -n 1000 -c 100 http://127.0.0.1:3000/
This is ApacheBench, Version 2.3 <$Revision: 1757674 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking 127.0.0.1 (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Completed 600 requests
Completed 700 requests
Completed 800 requests
Completed 900 requests
Completed 1000 requests
Finished 1000 requests


Server Software:
Server Hostname:        127.0.0.1
Server Port:            3000

Document Path:          /
Document Length:        12 bytes

Concurrency Level:      100
Time taken for tests:   1.304 seconds
Complete requests:      1000
Failed requests:        0
Total transferred:      133000 bytes
HTML transferred:       12000 bytes
Requests per second:    766.69 [#/sec] (mean)
Time per request:       130.431 [ms] (mean)
Time per request:       1.304 [ms] (mean, across all concurrent requests)
Transfer rate:          99.58 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   1.1      0       6
Processing:    17  125  21.6    128     157
Waiting:        3   71  36.5     70     142
Total:         23  125  20.6    128     157

Percentage of the requests served within a certain time (ms)
  50%    128
  66%    133
  75%    135
  80%    137
  90%    140
  95%    146
  98%    155
  99%    157
 100%    157 (longest request)
```

## Node.js http

### 実行環境
>21:22 $ node -v
v7.5.0

### レスポンス

>HTTP/1.1 200 OK
Connection: keep-alive
Content-Length: 12
Content-Type: text/plain
Date: Thu, 27 Apr 2017 11:33:51 GMT
>
>Hello world


### 計測結果

```
18:25 $ ab -n 1000 -c 100 http://127.0.0.1:1337/
This is ApacheBench, Version 2.3 <$Revision: 1757674 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking 127.0.0.1 (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Completed 600 requests
Completed 700 requests
Completed 800 requests
Completed 900 requests
Completed 1000 requests
Finished 1000 requests


Server Software:
Server Hostname:        127.0.0.1
Server Port:            1337

Document Path:          /
Document Length:        12 bytes

Concurrency Level:      100
Time taken for tests:   0.269 seconds
Complete requests:      1000
Failed requests:        0
Total transferred:      133000 bytes
HTML transferred:       12000 bytes
Requests per second:    3711.26 [#/sec] (mean)
Time per request:       26.945 [ms] (mean)
Time per request:       0.269 [ms] (mean, across all concurrent requests)
Transfer rate:          482.03 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    1   1.0      0       6
Processing:     9   25   8.8     23      48
Waiting:        8   25   8.7     23      48
Total:         13   26   8.8     23      50

Percentage of the requests served within a certain time (ms)
  50%     23
  66%     28
  75%     29
  80%     32
  90%     42
  95%     43
  98%     46
  99%     48
 100%     50 (longest request)
```

## SimpleHttpServer(Apple Python)

### 実行環境
>Python 2.7.13 (default, Apr  4 2017, 08:46:44)
[GCC 4.2.1 Compatible Apple LLVM 8.0.0 (clang-800.0.42.1)] on darwin

### レスポンス
>HTTP/1.0 200 OK
Connection: keep-alive
Content-Length: 12
Content-type: text/plain
Date: Thu, 27 Apr 2017 11:39:15 GMT
Server: BaseHTTP/0.3 Python/2.7.13
>
>Hello world


### 計測結果
```
18:56 $ ab -n 1000 -c 100 http://127.0.0.1:8080/
This is ApacheBench, Version 2.3 <$Revision: 1757674 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking 127.0.0.1 (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Completed 600 requests
Completed 700 requests
Completed 800 requests
Completed 900 requests
Completed 1000 requests
Finished 1000 requests


Server Software:        BaseHTTP/0.3
Server Hostname:        127.0.0.1
Server Port:            8080

Document Path:          /
Document Length:        13 bytes

Concurrency Level:      100
Time taken for tests:   0.845 seconds
Complete requests:      1000
Failed requests:        0
Total transferred:      151000 bytes
HTML transferred:       13000 bytes
Requests per second:    1182.74 [#/sec] (mean)
Time per request:       84.549 [ms] (mean)
Time per request:       0.845 [ms] (mean, across all concurrent requests)
Transfer rate:          174.41 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    5  37.1      0     528
Processing:     0    2   2.7      1      24
Waiting:        0    2   2.7      1      24
Total:          1    6  37.4      1     535

Percentage of the requests served within a certain time (ms)
  50%      1
  66%      2
  75%      2
  80%      2
  90%      4
  95%      7
  98%     24
  99%    213
 100%    535 (longest request)
```

## SimpleHttpServer (PyPy) 

#### 実行環境
>Python 2.7.13 (1aa2d8e03cdf, Mar 31 2017, 10:20:53)
[PyPy 5.7.1 with GCC 4.2.1 Compatible Apple LLVM 5.1 (clang-503.0.40)] on darwin


#### 計測結果

```
19:01 $ ab -n 1000 -c 100 http://127.0.0.1:8080/
This is ApacheBench, Version 2.3 <$Revision: 1757674 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking 127.0.0.1 (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Completed 600 requests
Completed 700 requests
Completed 800 requests
Completed 900 requests
Completed 1000 requests
Finished 1000 requests


Server Software:        BaseHTTP/0.3
Server Hostname:        127.0.0.1
Server Port:            8080

Document Path:          /
Document Length:        13 bytes

Concurrency Level:      100
Time taken for tests:   0.781 seconds
Complete requests:      1000
Failed requests:        0
Total transferred:      151000 bytes
HTML transferred:       13000 bytes
Requests per second:    1279.75 [#/sec] (mean)
Time per request:       78.140 [ms] (mean)
Time per request:       0.781 [ms] (mean, across all concurrent requests)
Transfer rate:          188.71 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    7  46.4      0     564
Processing:     0    1   2.4      1      19
Waiting:        0    1   2.4      0      19
Total:          1    9  46.5      1     567

Percentage of the requests served within a certain time (ms)
  50%      1
  66%      1
  75%      2
  80%      3
  90%      5
  95%     10
  98%    119
  99%    239
 100%    567 (longest request)
```

## 感想
luvit のパフォーマンスは特別高いわけではなさそうです。
ノンブロキングIOに旨味があることを踏まえると、大量にファイル書き込み等しないとあまり意味をなさないかもしれません。
それよりも Node.js のパフォーマンスの高さにビビります。うーん...勝てそうにない。
ただ、「[luvit.io vs node.js](http://qiita.com/hanishi@github/items/cd9e572126f898262d63)」によれば　luavit の方がパフォーマンスが高く計測されているんですよね。不思議。

## 追記

味をしめたのでついでに golang でもやってみることにしました。

## golang http

#### 実行環境

>00:42 $ go version
go version go1.8.1 darwin/amd64

#### レスポンス
>HTTP/1.1 200 OK
Content-Length: 12
Content-Type: text/plain; charset=utf-8
Date: Thu, 27 Apr 2017 15:38:44 GMT
>
>Hello, World

#### 計測結果
```
01:04 $ ab -n 1000 -c 100 http://127.0.0.1:8080/
This is ApacheBench, Version 2.3 <$Revision: 1757674 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking 127.0.0.1 (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Completed 600 requests
Completed 700 requests
Completed 800 requests
Completed 900 requests
Completed 1000 requests
Finished 1000 requests


Server Software:
Server Hostname:        127.0.0.1
Server Port:            8080

Document Path:          /
Document Length:        12 bytes

Concurrency Level:      100
Time taken for tests:   0.096 seconds
Complete requests:      1000
Failed requests:        0
Total transferred:      129000 bytes
HTML transferred:       12000 bytes
Requests per second:    10416.99 [#/sec] (mean)
Time per request:       9.600 [ms] (mean)
Time per request:       0.096 [ms] (mean, across all concurrent requests)
Transfer rate:          1312.30 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        1    4   1.2      4       8
Processing:     1    5   1.9      5      10
Waiting:        1    4   1.7      4       9
Total:          4    9   2.2      9      15

Percentage of the requests served within a certain time (ms)
  50%      9
  66%     10
  75%     11
  80%     11
  90%     12
  95%     13
  98%     14
  99%     14
 100%     15 (longest request)
```

す、すごいぜ golang。さすが21世紀のC。

## Simple-Web-Server(C++)

ここまできたら C++ でもやってみようかと。
[Simple-Web-Server](https://github.com/eidheim/Simple-Web-Server)の実装を借りてみる。

#### レスポンス
>HTTP/1.1 200 OK
Connection: keep-alive
Content-Length: 12
Content-Type: text/plain
>
>Hello world

#### 計測結果

```
02:01 $ ab -n 1000 -c 100 http://127.0.0.1:8080/
This is ApacheBench, Version 2.3 <$Revision: 1757674 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking 127.0.0.1 (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Completed 600 requests
Completed 700 requests
Completed 800 requests
Completed 900 requests
Completed 1000 requests
Finished 1000 requests


Server Software:
Server Hostname:        127.0.0.1
Server Port:            8080

Document Path:          /
Document Length:        12 bytes

Concurrency Level:      100
Time taken for tests:   0.196 seconds
Complete requests:      1000
Failed requests:        0
Total transferred:      97000 bytes
HTML transferred:       12000 bytes
Requests per second:    5103.79 [#/sec] (mean)
Time per request:       19.593 [ms] (mean)
Time per request:       0.196 [ms] (mean, across all concurrent requests)
Transfer rate:          483.46 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    1   1.5      0       6
Processing:     4   18   5.9     20      26
Waiting:        1   17   6.9     19      26
Total:          8   19   4.6     20      26

Percentage of the requests served within a certain time (ms)
  50%     20
  66%     21
  75%     22
  80%     23
  90%     24
  95%     26
  98%     26
  99%     26
 100%     26 (longest request)
```

うん速い。速いのですが、golang の http 実装よりはパフォーマンスが出ないのは意外な結果でした(もちろん使用する実装次第なのですが)。

## 感想(追記)
現在関わっている仕事で、大量のファイルをアーカイブする処理が Python と C で書かれています。この Python で書かれている部分を他の言語でリライトしたら高速化できるのではないかと思い立ち、チームでも採用されている lua で良い実装を探したところ luvit を見つけたのが検証の動機でした。結果、lua でもなく Node.js でもなく golang でリライトしようかと思えてきました（え...