文字列をキーにすると、シンボルよりも少し遅い
という記事を書いたんだけど、なんで差があるのかと。思った。
シンボルは内部的には整数だと言われている。
ということは、シンボルは生成されるたびに、対応する整数を作る必要があるはずだ。
ならば。
似たような処理を文字列とシンボルで行ったら、整数を作る分、シンボルのほうが遅かったりするんじゃないかと思った。
シンボルと文字列で同じような処理といえば、succ
。
というわけで、例によっていい加減なコードで比較してみた。
こんな
require "benchmark"
N=1_000_000
print "ruby #{RUBY_VERSION}|"
k=("a"*1000)
print "%.3f|" % ( Benchmark.realtime do
N.times do |n|
k=k.succ
end
end )
k=("a"*1000).freeze
print "%.3f|" % ( Benchmark.realtime do
N.times do |n|
k=k.succ.freeze
end
end )
k=("c"*1000).to_sym
print "%.3f|" % ( Benchmark.realtime do
N.times do |n|
k=k.succ
end
end )
puts
感じ。
実行してみると:
通常文字列 | frozen文字列 | シンボル | |
---|---|---|---|
ruby 2.4.2 | 0.438 | 0.477 | 8.760 |
ruby 2.3.5 | 0.423 | 0.443 | 13.615 |
ruby 2.2.7 | 0.456 | 0.469 | 12.952 |
こんな感じ。
2.3 と 2.4 の間に何かあったらしい。
ありがとうございます。
それはともかく。
1000文字あると、シンボルは 20倍くらい遅い。
つまりやっぱり、生成時にコストを掛けることで比較を速くしているということなんだろう。
と思うと謎なのは frozen文字列。なんで比較が速くなるんだろう。そもそも速くなっているのかどうか。気になるけど今日のところはこれぐらいで。