最近、I18n のデフォルトの Simple I18n バックエンドから Redis バックエンドに切り替えました。翻訳を処理しやすくするためにそうしましたが、すべてのページでかなりのパフォーマンス ヒットがあったことがわかりました。
Rails 3.2 と Redis 2.6.4 を MBP にインストールしていくつかのベンチマークを実行し、デモを行いました。クライアントとしてhiredis-rbを使用しています。
2 つの異なるバックエンドを実行すると、その違いは明らかです。単純なバックエンドでは、最初の呼び出しに短い遅延があります - 翻訳がメモリにロードされていると仮定します - その後、優れたパフォーマンスが得られます:
pry(main)> Benchmark.realtime { 500.times { I18n.t 'shared.slogan' } }
=> 0.143246
pry(main)> Benchmark.realtime { 500.times { I18n.t 'shared.slogan' } }
=> 0.00415
pry(main)> Benchmark.realtime { 500.times { I18n.t 'shared.slogan' } }
=> 0.004153
pry(main)> Benchmark.realtime { 500.times { I18n.t 'shared.slogan' } }
=> 0.004056
Redis バックエンドは一貫して遅い:
pry(main)> Benchmark.realtime { 500.times { I18n.t 'shared.slogan' } }
=> 0.122448
pry(main)> Benchmark.realtime { 500.times { I18n.t 'shared.slogan' } }
=> 0.263564
pry(main)> Benchmark.realtime { 500.times { I18n.t 'shared.slogan' } }
=> 0.232637
pry(main)> Benchmark.realtime { 500.times { I18n.t 'shared.slogan' } }
=> 0.122304
なぜこれが I18n で遅いのか、私には完全に理にかなっています...コードベース全体で何十もの I18n 呼び出しをキューに入れています。それらを前もってバッチ処理できれば、私は良い状態になるでしょう:
pry(main)> keys = $redis.keys[0..500]
pry(main)> Benchmark.realtime { $redis.mget keys }
=> 0.04264
しかし、既存の I18n バックエンドのいずれかでこれを行うクリーンな方法は実際には見当たりません。この問題に取り組んだ人はいますか?
編集
私は Chris Heald の提案を受けて、単純なキャッシュ バストをメモ化するバックエンドを作成しました。要点はここにあります:
https://gist.github.com/wheeyls/5650947
これを数日間試してから、宝石に変えます。
アップデート
私のソリューションは現在gemとして利用できます:
https://github.com/wheeyls/cached_key_value_store
そして、私はこの問題についてブログにも書きました: