I recently switch from the default Simple I18n backend to a Redis backend for my I18n. I did it so make it easier for us to handle the translations, but I've found that there was a substantial performance hit on every page.
I've run some Benchmarks with Rails 3.2 and Redis 2.6.4 installed on my MBP to demonstrate. I'm using hiredis-rb as my client.
It's a pretty clear difference when exercising the two different backends. With the simple backend there is a short delay on the first call - I assume the translations are being loaded into memory - and then great performance after that:
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
The Redis backend is consistently slow:
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
It makes absolute sense to me why this is slow for I18n... I'm queueing up dozens of I18n calls throughout my code base. If I could batch them together up front I'd be in good shape:
pry(main)> keys = $redis.keys[0..500]
pry(main)> Benchmark.realtime { $redis.mget keys }
=> 0.04264
But I don't really see a clean way to do this with any of the existing I18n backends. Has anybody out there tackled this problem?
EDIT
I took Chris Heald's suggestion and created a backend with memoization a simple cache bust. The gist is up here:
https://gist.github.com/wheeyls/5650947
I'll try this out for a few days and then turn it into a gem.
UPDATE
My solution is available as a gem now:
https://github.com/wheeyls/cached_key_value_store
And I also blogged about this problem: