Edited at

ActiveRecordを高速化するAdequateRecordは何をするものか


TL;DR


  • AdequateRecordはActiveRecordの機能の名前


    • 新しいgemとかでは無い




  • #find #find_by そして #find_by_XXXを2倍に高速化する


    finder_ips.png

    引用: AdequateRecord Pro™: Like ActiveRecord, but more adequate | Tenderlovemaking





  • 内部的にはクエリ呼び出しの度にActiveRecordが生成するオブジェクトをキャッシュする


    • 対象を#findなどに限っているのは、生成されるオブジェクトや条件が単純だから




Rails 4.2.0 beta1 リリース

先日Rails 4.2.0 beta1がリリースされて、そのリリースブログの中にAdequate Recordなるものが


ActiveRecordの動作

ActiveRecordの#whereなどを使ってDBからレコードを引っ張ってくる場合、中ではだいたいこんなことが起きる(らしい)



  1. ActiveRecord::Relationが構築される



    • #whereとか#orderとかの呼び出され方とかを記憶してる



  2. そこからARel::Nodeを作る


    • DBMSに寄らない抽象構文木(AST)

    • ArelはSQL ASTを扱うためのRubyライブラリらしい



  3. SQL文字列を作ってDBに渡す

  4. 返ってきたレコードからインスタンスを生成


AdequateRecordがやること(推測)

#find #find_by #find_by_XXXの3つの形式の呼び出しを行った時に、最初の一回目だけActiveRecord::Relationを作って、それ以降はそこを経由せずに直接ARel::Nodeにいく。

ARel::Node自体をキャッシュしているのか、それの作り方をキャッシュしているのかは知らない。

#whereに適応されないのは、取りうる場合の数が非常に多いため。それと#where#orderはメソッドチェインして使うので、どうしてもActiveRecord::Relationを作らざるを得ない。一方、#find系メソッドは返り値がモデルインスタンスなので、それ以上ActiveRecord::Relationに対して変更を加えないことが分かるので、それの生成をスキップできる。


感想

インタフェースへの変更無しにパフォーマンスが改善されるのは非常に嬉しい。

ベンチマークを見る限りActiveRecord::Relationの生成がそもそも重たいっぽいので、そちら側のパフォーマンス改善にも期待したい。


参考