Elixir/PhoenixでISUCON5予選の参考実装を書いた
October 21, 2015 - Elixir
ISUCON5予選の参考実装を、Elixir/Phoenixで実装してみました。
It (partially) works! #myelixirstatus pic.twitter.com/NuhhufXAwC
— Masaki YOSHIDA (@ReSTARTR) 2015, 10月 20
汚いながらもとりあえずひととおり動いたので現時点でのコードをGithubにpush。
実装について補足
まずは他言語の初期実装と同等のSQLを再現することを目標としました。
Goの実装を参考に、まずは各ページを実装してブラウザでひととおり機能が実装できているか確認。 その後ベンチマークをすべて通過するまでひたすら修正するという手順ですすめました。
そのため、テンプレートの細かい表示(時刻フォーマット等)の不備や、ベンチマーカーがチェックしない機能が抜けている可能性があります。
注意点
ベンチマーカーがCSSファイルのサイズを厳密にチェックしていて、なぜか1バイト余計に増えてしまってパスしない問題が発生します。
チェック箇所のサイズを122540
から122541
にすることで無理やりとおしました。
原因は追って調査ですが、機能的に問題ないはずなので一時しのぎです。
ベンチマーク結果
気になる性能ですが、Goと比較すると以下のような結果となりました。
※VirtualBox上にたてたMySQLにたいして、ホストのMacOSX上でアプリケーションを実行しています
Lang | requests | elapsed | success | redirect | failure |
---|---|---|---|---|---|
Elixir/Phoenix | 333 | 76093 | 239 | 93 | 1 |
Go | 138 | 106728 | 98 | 39 | 1 |
スコア計算式をもとに計算してみると以下のようなスコアとなります(eror, exception, violationsはないので減点は無し)
# Elixir/Phoenix
irb(main):001:0> base_score = 239 + 93 * 0.1
=> 248.3
# Go
irb(main):002:0> base_score = 98 + 39 * 0.1
=> 101.9
同じクエリを再現したうえで、だいたい2.5倍くらいの性能差?でしょうか。 が、完全に模倣できているか自信はないのであくまで参考程度ということで…
以下にベンチマーカーの出力内容も貼っておきます。
elixir/phoenix版の結果
{
"valid" : true,
"requests" : 333,
"elapsed" : 76093,
"done" : "[{Isucon5InitExecutor},{BootstrapChecker},{Isucon5Load,Isucon5Load,Isucon5Load,Isucon5Load,Isucon5Checker}]",
"responses" : {
"success" : 239,
"redirect" : 93,
"failure" : 1,
"error" : 0,
"exception" : 0
},
"violations" : [ ]
}
BUILD SUCCESSFUL
Total time: 1 mins 27.449 secs
go版の結果
{
"valid" : true,
"requests" : 138,
"elapsed" : 106728,
"done" : "[{Isucon5InitExecutor},{BootstrapChecker},{Isucon5Load,Isucon5Load,Isucon5Load,Isucon5Load,Isucon5Checker}]",
"responses" : {
"success" : 98,
"redirect" : 39,
"failure" : 1,
"error" : 0,
"exception" : 0
},
"violations" : [ ]
}
BUILD SUCCESSFUL
Total time: 1 mins 54.937 secs
今後
今回のISUCONアプリは結構機能を積んでいるため、Elixir/Phoenixに慣れるにはちょうど良いテーマなのではないかと思います。
ただPhoenix初心者ということもあり、実装していたほとんどの時間は”Ectoでどうやってクエリを再現するか”に使っていて、 ロジックの書き方とか各モジュールの使い分けとかまであまり気にできてません。 Phoenix/Ectoの有効性を台無しにしていること間違いなし… まぁ、そこんところはおいおい感覚をつかんでいこうかな、と。
このあとはEctoの抽象化を活かしつつさらに最適化をすすめていったときに、どのような性能を発揮するのか気になるところです。