filterのパフォーマンステスト

before_filter, after_filter, around_filter を枚数重ねて、
どのくらいパフォーマンスに影響が出るのかをざっくり調べてみた

環境

  • App Server
    • Amazon EC2: Large Instance
    • Apache: デフォルト設定
    • Ruby: 1.8.7
    • Passenger
      • RailsEnv: production
      • RailsMaxPoolSize: 30
      • RailsPoolIdleTime: 1200
    • Rails: 2.3.8
  • Request Server
    • Amazon EC2: Large Instance
    • ab (Apache Bench) でApp Serverに対してリクエス
      • 100件同時接続を5秒間続けて、どれくらいリクエストを処理できたかを見る
$ ab -c 100 -t 5 http://ec2-***.amazonaws.com/filter_check

結果

先に結果を

上記、abコマンドを10回実行した平均の「Complete requests*1」「Requests per second*2」を結果とした

表の項目名定義

  • ctrler_10: コントローラ内の同一メソッドを10枚
  • ctrler_100: コントローラ内の同一メソッドを100枚
  • cls_10: filterクラス(new無し)を10枚
  • cls_100: filterクラス(new無し)を100枚
  • cls_new_10: filterクラス(new有り)を10枚
  • cls_new_100: filterクラス(new有り)を100枚

なお、filterの中身は空

filter 無し
  • Complete requests: 2442.1
  • Requests per second: 487.897
before_filter

  ctrler_10 ctrler_100 cls_10 cls_100 cls_new_10 cls_new_100
Complete requests 2255.1 1543.9 2148 1492.4 2244.6 1467.5
Requests per second 450.536 308.538 429.212 298.123 448.455 293.194

after_filter

  ctrler_10 ctrler_100 cls_10 cls_100 cls_new_10 cls_new_100
Complete requests 2245.1 1482 2205 1555.8 2187.3 1444.5
Requests per second 448.375 295.654 440.341 310.75 436.62 288.5

around_filter

  ctrler_10 ctrler_100 cls_10 cls_100 cls_new_10 cls_new_100
Complete requests 1864 167 1465.3 15 1453.9 11.8
Requests per second 372.369 33.291 292.664 2.902 290.409 2.292

before_filter & after_filter

  ctrler_10 ctrler_100 cls_10 cls_100 cls_new_10 cls_new_100
Complete requests 2079 1071.6 2077.3 1011.8 2038.7 1042.4
Requests per second 415.254 214.024 415.154 201.969 407.193 208.08

感想

before_filter, after_filter 10枚くらいだと、
コントローラ内メソッドでも、filterクラスでもそれほど差はないし、
問題になるほどではなさそう。


around_filter は結構重い
おまけに、コントローラ内メソッドではなく、filterクラスだとさらに。。。

コード

### app/controllers/filter_check_controller.rb
class FilterCheckController < ApplicationController
  # ctrler_10,100
  #before_filter :ctrler_before_filter, :ctrler_before_filter, :ctrler_before_filter, ...

  # cls_10,100
  #before_filter TestFilter, TestFilter, TestFilter, ...

  # cls_new_10,100
  #before_filter TestFilter2.new, TestFilter2.new, TestFilter2.new, ...


  def index
    render :text => "done"
  end

  private
  # コントローラ内のfilter用メソッド
  def ctrler_before_filter
  end

  def ctrler_after_filter
  end

  def ctrler_around_filter
    yield
  end
end

### lib/test_filter.rb
# filterクラス(new無し)
class TestFilter
  def self.before(controller)
  end
  def self.after(controller)
  end
end

### lib/test_filter2.rb
# filterクラス(new有り)
class TestFilter2
  def before(controller)
  end

  def after(controller)
  end
end

*1:処理できたリクエスト総数

*2:1秒間に処理したリクエスト数