続けて、JavaとNode.jsとGoで外部ライブラリを使わないベンチマークをしてみた。
前回の記事では、DynamoDBを呼び出す処理の簡単なベンチマークを行いました。
http://d.hatena.ne.jp/cero-t/20160101/1451665326
ライブラリを伴ったときの初回起動ではJavaが不利な感じの結果になりましたが、ライブラリを使わなければどのような差が出るのか、改めて確認してみました。
今回のベンチマークは、フィボナッチ数列の38番目を取るというものです。
ソースコードは前回と同じリポジトリに追加しています。
https://github.com/cero-t/lambda-benchmark
結果
回数 | Java | Node.js | Go |
---|---|---|---|
1回目 | 2.919 | 9.28 | 4.14 |
2回目 | 2.678 | 9.302 | 4.141 |
3回目 | 2.579 | 9.396 | 4.14 |
時間はいずれも秒。ミリ秒より下の精度は切り捨て。
今回はいずれもメモリ128MBで、同じ性能の環境で実施しました。
なおBilled Durationは、ほぼこの結果の2倍程度(=ウォームアップのための実行分)になっていて、オーバーヘッドはあまり感じられませんでした。
メモリの実使用量は
Java : 12MB
Node.js : 9MB
Go : 10MB
でした。
Python書けないマンなので、Pythonは計測していません。
他のサイトのベンチマークを見る限りは、数十秒から数分ぐらい掛かりそうな気がします。
考察
Javaが一番早く、Goはその1.5倍ぐらい、Node.jsはJavaの3倍ぐらい時間が掛かるという結果でした。
ウォームアップをもうちょっと取ればJavaのJITコンパイルが効くのかも知れませんが、Lambdaで動かすという性質上、本来ならウォームアップなしで動かしたいぐらいなので、これぐらいの比較で十分かと思います。
ちなみに僕の手元のMacBook Pro(Late 2013 / Core i5 2.4GHz)だと、Javaで0.28秒ぐらい、Goで0.33秒ぐらいでしたから、メモリ128MBのLambdaの性能はその1/10ぐらいということになりますね。
もちろん今回は対象がフィボナッチ数の計算という一つの処理なので、結果的にJavaが良かっただけかも知れません。様々なアルゴリズムで言語のベンチマークを行っているサイトでは、Goの方が有利な結果もいくつか出ています。
https://benchmarksgame.alioth.debian.org/u64q/go.html
ということで、ライブラリのローディングさえなければ、Javaだって悪くないということが分かりました。
まぁ実際、ライブラリを使わないことなんて、ほぼ考えられないですけどね!