Elixir/PhoenixでISUCON5予選の参考実装を書いた

October 21, 2015 - Elixir

ISUCON5予選の参考実装を、Elixir/Phoenixで実装してみました。

汚いながらもとりあえずひととおり動いたので現時点でのコードを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の抽象化を活かしつつさらに最適化をすすめていったときに、どのような性能を発揮するのか気になるところです。