早々にすみません、諸事情によりコードはお見せできず、サンプルコードで例を示します。
改善前
下記のコントローラーでは、user_nameというカラムをnameという別名のkeyで返したいが為に入れ替えを行っている。
※実際にはもっと色々なフィールドを移し替えていました。
def index
all_user = []
User.all.each do |user|
hash = {
id: user.id,
name: user.user_name
}
all_user.push(hash)
end
render all_user
end
改善後
下記のコードの場合は取得後に移し替えるのではなく、AS句を使って取得と整形を同時に行っている
def index
render User.select("id, user_name AS name").as_json
end
結果
厳密にはサンプルコードの結果ではないのですが、手元にあるAPIのINDEXメソッドでは1000件ほどのレコード数の場合、改修前後で約380msの違いが出ました。
| 改善 | 速度(ms) |
|---|---|
| 前 | 560ms |
| 後 | 180ms |
| 計 | -380ms |
感想
380msはデカいです。。
参考のコードはかなりシンプルになってしまったのですが、実際のコードでは改善前後で行数や複雑度はそこまで変わりませんでした。
あまり変わらないのであれば改善前のようにActiveRecordオンリーで書くスタイルの方が一般的には(少なくとも私の現場では)良いとされているため、改善後のようなSQL混じりのコードを書くことは避けられる傾向にあります。
しかし速度の面でSQLは無視できないメリットがあるため、うまく改行を使ったり、スコープとして切り出すなどしてSQL混じりでも読みやすいようなスタイルを取り入れるのも十分に検討の余地があるなと。
まとめ
- 一時変数のhashに代入しまくっている箇所があったら怪しいと思った方が良い
- 素直にAS句で取り出してそのまま使う方が速い
- SQL混じりでも読みやすいスタイルを検討する