search
LoginSignup
3

More than 5 years have passed since last update.

posted at

文字列をキーにすると、シンボルよりも少し遅い

プロを目指す人のためのRuby入門 を今読んでいる。

で。ちょっときになることがあった。

152ページ、5.3.2 に
「シンボルを使って値を取り出す(文字列より高速)」
とある。どれぐらい違うんだろう。と思った。

またいい加減なコードで時間を測ってるんだけど、こんな感じ:

require "benchmark"

hsym={}
hstr={}
k=:a
ARGV[0].to_i.times do
  hsym[k=k.succ]=0
  hstr[k.to_s]=0
end

key_sym = hsym.keys.shuffle
key_str = key_sym.map(&:to_s)
size = key_sym.size
N=10_000_000

print "%.3f|" % ( Benchmark.realtime do
  N.times do |n|
    b=hsym[key_sym[n % size]]
  end
end )
print "%.3f|" % ( Benchmark.realtime do
  N.times do |n|
    b=hstr[key_str[n % size]]
  end
end )
puts

■h略.size==3

シンボル 文字列
ruby 2.4.2 0.835 1.340
ruby 2.3.5 0.769 1.290
ruby 2.2.7 0.846 1.350

■h略.size==1000000

シンボル 文字列
ruby 2.4.2 4.194 5.112
ruby 2.3.5 5.655 6.360
ruby 2.2.7 5.605 6.163

やっぱりシンボルが速い。
とはいえ、思ったほどではない。倍以上は違うと予想していた。

文字列/シンボルの長さを変えて再挑戦。
こんな

require "benchmark"

hsym={}
hstr={}
k=("a"*100).to_sym
ARGV[0].to_i.times do
  hsym[k=k.succ]=0
  hstr[k.to_s]=0
end

key_sym = hsym.keys.shuffle
key_str = key_sym.map(&:to_s)
size = key_sym.size
N=10_000_000

print "%.3f|" % ( Benchmark.realtime do
  N.times do |n|
    b=hsym[key_sym[n % size]]
  end
end )
print "%.3f|" % ( Benchmark.realtime do
  N.times do |n|
    b=hstr[key_str[n % size]]
  end
end )
puts

感じで。

■h略.size==3

シンボル 文字列
ruby 2.4.2 0.822 1.844
ruby 2.3.5 0.793 1.734
ruby 2.2.7 0.842 1.773

■h略.size==1000000

シンボル 文字列
ruby 2.4.2 4.152 6.883
ruby 2.3.5 5.424 8.177
ruby 2.2.7 5.698 8.088

キーが長くなると差が開いた。なるほど。

それとは別に。
ハッシュのサイズが大きくなると差が開くと予想していたんだけど、むしろ縮んでいる。予想が外れた。難しいね。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
3