青山です。

順番によってトータルの時間まで変わるようです。

$ 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>