我最近从默认的 Simple I18n 后端切换到 I18n 的 Redis 后端。我这样做是为了让我们更容易处理翻译,但我发现每个页面的性能都会受到很大影响。
我在 MBP 上安装了 Rails 3.2 和 Redis 2.6.4 运行了一些基准测试来演示。我使用hiredis-rb作为我的客户。
在执行两个不同的后端时,这是一个非常明显的区别。使用简单的后端,第一次调用会出现短暂的延迟——我假设翻译正在加载到内存中——然后表现出色:
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
我还写了一篇关于这个问题的博客: