TL;DR
-
AdequateRecordはActiveRecordの機能の名前
- 新しいgemとかでは無い
-
#find
#find_by
そして#find_by_XXX
を2倍に高速化する
引用: 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からレコードを引っ張ってくる場合、中ではだいたいこんなことが起きる(らしい)
-
ActiveRecord::Relation
が構築される-
#where
とか#order
とかの呼び出され方とかを記憶してる
-
- そこから
ARel::Node
を作る- DBMSに寄らない抽象構文木(AST)
- ArelはSQL ASTを扱うためのRubyライブラリらしい
- SQL文字列を作ってDBに渡す
- 返ってきたレコードからインスタンスを生成
AdequateRecordがやること(推測)
#find
#find_by
#find_by_XXX
の3つの形式の呼び出しを行った時に、最初の一回目だけActiveRecord::Relation
を作って、それ以降はそこを経由せずに直接ARel::Node
にいく。
ARel::Node
自体をキャッシュしているのか、それの作り方をキャッシュしているのかは知らない。
#where
に適応されないのは、取りうる場合の数が非常に多いため。それと#where
や#order
はメソッドチェインして使うので、どうしてもActiveRecord::Relation
を作らざるを得ない。一方、#find
系メソッドは返り値がモデルインスタンスなので、それ以上ActiveRecord::Relation
に対して変更を加えないことが分かるので、それの生成をスキップできる。
感想
インタフェースへの変更無しにパフォーマンスが改善されるのは非常に嬉しい。
ベンチマークを見る限りActiveRecord::Relation
の生成がそもそも重たいっぽいので、そちら側のパフォーマンス改善にも期待したい。