Skip to content

Instantly share code, notes, and snippets.

@vjoel vjoel/i18n-intern.rb
Last active Aug 29, 2015

Embed
What would you like to do?
# in response to http://littlelines.com/blog/2014/06/27/elixir-vs-ruby-showdown-part-one
# comment on https://twitter.com/josevalim/status/483165833699799040
require 'yaml'
module I18n
SPEC = YAML.load(<<-END)
en:
foo: "bar"
flash:
notice:
alert: "Alert!"
hello: "hello %{first} %{last}"
bye: "bye now %{name}!"
users:
title: "Users"
profiles:
title: "Profiles"
END
@cache = {}
def self.clear_cache
@cache = {}
end
def self.t(path, **opts)
case handler = @cache[path]
when Proc
handler[opts]
when nil
parts = path.to_s.
split(".").
inject(SPEC["en"]) { |r,v| r[v] }.
split(/%\{(\w+)\}/)
if parts.size == 1
@cache[path] = parts[0]
else
code = "result = #{parts.shift.inspect}\n"
loop do
var = parts.shift
break unless var
code << "result << ops[:#{var}]\n"
str = parts.shift
break unless str
code << "result << #{str.inspect}\n"
end
code = %{
proc do |ops|
#{code}
end
}
@cache[path] = handler = eval(code)
handler[opts]
end
else
handler
end
end
end
if ARGV.delete("--test")
p I18n.t("foo")
p I18n.t("users.profiles.title")
p I18n.t("flash.notice.hello", first: "chris", last: "mccord")
p I18n.t(:"flash.notice.hello", first: "john", last: "doe")
exit
end
require 'benchmark'
N = 1_000_000
Benchmark.bm(20) do |bm|
bm.report("string args") do
I18n.clear_cache
N.times do
I18n.t("foo")
I18n.t("users.profiles.title")
I18n.t("flash.notice.hello", first: "chris", last: "mccord")
I18n.t("flash.notice.hello", first: "john", last: "doe")
end
end
bm.report("symbol args") do
I18n.clear_cache
N.times do
I18n.t(:"foo")
I18n.t(:"users.profiles.title")
I18n.t(:"flash.notice.hello", first: "chris", last: "mccord")
I18n.t(:"flash.notice.hello", first: "john", last: "doe")
end
end
end
__END__
$ cat /proc/cpuinfo | grep 'model name' | uniq
model name : Intel(R) Core(TM) i7-4500U CPU @ 1.80GHz
$ ruby -v
ruby 2.1.2p95 (2014-05-08 revision 45877) [x86_64-linux]
$ ruby i18n-intern.rb
user system total real
string args 3.560000 0.010000 3.570000 ( 3.571387)
symbol args 3.250000 0.010000 3.260000 ( 3.252616)
# in response to http://littlelines.com/blog/2014/06/27/elixir-vs-ruby-showdown-part-one
require 'yaml'
module I18n
SPEC = YAML.load(<<-END)
en:
foo: "bar"
flash:
notice:
alert: "Alert!"
hello: "hello %{first} %{last}"
bye: "bye now %{name}!"
users:
title: "Users"
profiles:
title: "Profiles"
END
@cache = {}
def self.t(path, **opts)
case handler = @cache[path]
when Proc
handler[opts]
when nil
spec = path.split(".").inject(SPEC["en"]) { |r,v| r[v] }
parts = spec.split(/%\{(\w+)\}/)
if parts.size == 1
@cache[path] = parts[0]
else
code = "result = #{parts.shift.inspect}\n"
loop do
var = parts.shift
break unless var
code << "result << ops[:#{var}]\n"
str = parts.shift
break unless str
code << "result << #{str.inspect}\n"
end
code = %{
proc do |ops|
#{code}
end
}
@cache[path] = handler = eval(code)
handler[opts]
end
else
handler
end
end
end
if ARGV.delete("--test")
p I18n.t("foo")
p I18n.t("users.profiles.title")
p I18n.t("flash.notice.hello", first: "chris", last: "mccord")
p I18n.t("flash.notice.hello", first: "john", last: "doe")
exit
end
require 'benchmark'
N = 1_000_000
class Benchmarker
def self.run
Benchmark.measure do
N.times do |i|
I18n.t("foo")
I18n.t("users.profiles.title")
I18n.t("flash.notice.hello", first: "chris", last: "mccord")
I18n.t("flash.notice.hello", first: "john", last: "doe")
end
end.real
end
end
p Benchmarker.run
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.