青山です。
順番によってトータルの時間まで変わるようです。
$ ruby -e "
require 'jcode'
class String
def jlength2
gsub(/./p, ' ').length
end
end
a = 'aあ' * 200_000
t = Time.now
p a.jlength2
t1 = Time.now
p a.jlength
t2 = Time.now
p [t1 - t, t2 - t1]
"
400000
400000
[3.092081, 12.084014]
$ ruby -e "
require 'jcode'
class String
def jlength2
gsub(/./p, ' ').length
end
end
a = 'aあ' * 200_000
t = Time.now
p a.jlength
t1 = Time.now
p a.jlength2
t2 = Time.now
p [t1 - t, t2 - t1]
"
400000
400000
[11.87527, 27.22549]
単独の場合はこんな感じでしょうか。
split は巨大な配列を生成するので遅い。それとも、// のマッチが重い?
$ time ruby -e 'p( ("aあ"*1000*1000).split(//).length )'
2000000
real 3m40.193s user 3m35.600s sys 0m1.340s
scan はブロックを渡すと配列を返さないので速い。
$ ruby -e 'p( ("aあ"*10).scan(/./p){} )'
"aあaあaあaあaあaあaあaあaあaあ"
$ time ruby -e 'l=0; ("aあ"*1000*1000).scan(/./p){l+=1}; p l'
2000000
real 0m27.060s user 0m26.990s sys 0m0.060s
gsub は使い込まれている事もあり、さらに速い。
$ time ruby -e 'p( ("aあ"*1000*1000).gsub(/./p, " ").length )'
2000000
real 0m15.519s user 0m15.300s sys 0m0.220s
gsub の速さと length の速さは scan や多数の加算よりも上のようですね。
--
青山 和光 Wakou Aoyama <wakou / fsinet.or.jp>