無印吉澤

Site Reliability Engineering(SRE)、ソフトウェア開発、クラウドコンピューティングなどについて、吉澤が調べたり試したことを書いていくブログです。

Phoenix Framework に関する有名なベンチマーク同士の関係

f:id:muziyoshiz:20161224204900p:plain

Phoenix Framework(以下、Phoenix)は、Elixir のための Web アプリケーションフレームワークです。

Phoenix の開発者 José Valim 氏は Ruby on Rails のコミッタだったため(Rails Contributors - #5 José Valim を見る限り、2014年まで?)、使い勝手はとても Rails に似ています。そのため、Phoenix は Rails とよく比較され、「Rails よりも10倍近く速い」という評判を時々目にします。

ただ、その評判の出処になったベンチマークについて、僕は具体的な内容を知りませんでした。また、記事によってベンチマークのリンク先がまちまちで、それぞれの関係がよくわかりませんでした。自分で Phoenix を使ってみるにあたり、このあたりを少し調べてみたので、その結果をメモしておきます。

最初のベンチマーク

Phoenix と Rails に関する最初のベンチマークは、Chris McCord(Programming Phoenix: Productive, Reliable, Fast の著者)による2014年7月のブログ記事のようです。

littlelines.com

この記事は「Phoenix は Rails より10.63倍速い」というベンチマーク結果を示しています。ちなみに、これは Elixir vs Ruby Showdown というシリーズの2番目のポストで、最初のポスト(Elixir vs Ruby Showdown - Part One)では「Ruby の i18n gem と比較して Elixir 版は73倍速い」という結果を出してます。

このベンチマークの内容は以下のようなものです。この特徴は、後述する他のベンチマークにも引き継がれています。

  • URL ‘/:title’ の :title 部分をコントローラに渡す
  • コントローラは、モデルの返り値を想定したマップ(固定値)の配列をビューに渡す
  • ビューは、受け取った配列を回して HTML を生成し、クライアントに返す
  • データベースへのアクセスは行わない
  • ログ出力は行わない
  • ENV = production で動作させる
  • ベンチマークツールには wrk を使って、30秒間テストする

具体的なコードの説明も載っているので、後述するベンチマークを読むにしても、まずこのブログ記事は読んでおいた方が良いです。

ベンチマーク対象の拡大

その後、このベンチマークに触発されて、ベンチマーク対象を他のフレームワークに広げたものが Matthew Rosenberg 氏により公開されました。

github.com

Phoenix は、Rails よりむしろ Sinatra に似た軽量フレームワークではないか、との理由から、比較対象は主に Sinatra にインスパイヤされたフレームワークから選ばれています。また、Phoenix の実装の基盤である Plug というライブラリを素で使った場合も追加されています。

  • Phoenix (Elixir)
  • Plug (Elixir)
  • Rails (Ruby)
  • Sinatra (Ruby)
  • Express, Express Cluster (JavaScript)
  • Martini (Go)
  • Gin (Go)
  • Play Framework (Java)

このテストは、Phoenix のバージョンアップに合わせて、何度か実施されています。

Round 1 と 2-3 はスペックが違うので単純に比較できません。

  • Round 1: 3.4GHZ Core i7 (quad core), 12GB RAM
  • Round 2-3: 4.0GHZ Core i7 (quad core), 32GB RAM

Round 1 はスペックが低いので、単純比較できるのは Round 2 と 3 のみです。Phoenix の結果だけ比較すると、Round 3 は 2 よりも若干遅くなっています。Plug の結果はほとんど変わっていないので、Phoenix に機能が増えたからでしょうか?

Round 3 の結果を見ると、Phoenix は Play より Consistency は優れているものの、Throughput は Play の約 0.47 倍となっています。Elixir は stop-the-world GC がないので Java より高速、と思っていたので、最初にこの結果を見たときはかなりがっかりしました。

高スペックなベアメタルサーバ上での結果

2015年7月に、上記の phoenix-showdown を Rackspace のベアメタルサーバ(CPU Dual 2.8 Ghz, 10 core, RAM 128 GB)で実行した結果が公開されました。

Comparative Benchmark Numbers @ Rackspace

スペックが高いほど Elixir の真価が発揮されるのか、このベンチマークでは、Phoenix の throughput は Play とほぼ同じか若干上で、Consistency では引き続き上回っています。Rails との差は更に開いて、Phoenix の throughput は Rails の15倍になっています。

感想(と職場ブログの宣伝)

素の状態では、Phoenix は Rails よりも10倍以上高速なのは確かなようです。ただ、他のコンパイル言語(Java や Go)と比較すると、throughput については決定的な差は無さそうです。

また、これらのベンチマークはデータベースアクセスやログ出力といった、普通のアプリには絶対にある機能を省いているので、周辺ライブラリの充実度によっては、開発者の多い Java & Play Framework で実装した方が、総合的には速くなるのかもしれません。Rails 開発者が多い環境なら Phoenix に飛びついてもよさそうですが、Java 開発者が多い環境では Play のほうが速い、ということもあるのかもしれません。

そのあたりが気になって、Elixir (その2)とPhoenix Advent Calendar 2016 の24日目として、Phoenix で書いた簡単なアプリケーションサーバに、HBase アクセスや、ファイルへのログ出力を足したら、性能はどう変わるか、という話を書きました。時間の都合で Play との比較まではできていませんが、今後気が向いたらそこまで試してみたいと思っています。

recruit.gmo.jp

記事の公開後に教えてもらったページ

togetter.com