前書き
luvit という 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 GMTHello 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 GMTHello 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.13Hello 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」によれば 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 GMTHello, 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の実装を借りてみる。
レスポンス
HTTP/1.1 200 OK
Connection: keep-alive
Content-Length: 12
Content-Type: text/plainHello 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 でリライトしようかと思えてきました(え...