Ruby1.9で長い文字列を比較的早く作成する方法
UTF-8を使って100MBのクエリーを作成したら激遅だったので,いろいろ調べてみた.
あんまり調べてないけど
UTF-8の文字列を使用せず,バイナリ(ASCII-8BIT)を使用するというのが1番早いんではなかろうかと予想
なので比較してみる
クエリー作成時は範囲での入れ替えをよくやるので範囲オブジェクト使うために2文字にした
比較用コード
#-*- encoding:UTF-8 -*- times = ARGV[0].to_i puts times.to_s + "回" #文字列を+でつなげる a = "" b = "aa" start_time = Time.now (0...times).each do |i| a += b end end_time = Time.now puts "その1:+でつなげる" puts "全体の時間:"+(end_time - start_time).to_s puts "1回あたり:"+((end_time - start_time)/times).to_s,"" #文字列を入れ替える(UTF-8で) a = (" " * times * 2).force_encoding("UTF-8") b = "aa".force_encoding("UTF-8") start_time = Time.now (0...times).each do |i| a[(i*2)..(i*2+1)] = b end end_time = Time.now puts "その2:UTF-8で入れ替え" puts "全体の時間:"+(end_time - start_time).to_s puts "1回あたり:"+((end_time - start_time)/times).to_s,"" #文字列を入れ替える(バイナリで) a = (" " * times * 2).force_encoding("ASCII-8BIT") b = "aa".force_encoding("ASCII-8BIT") start_time = Time.now (0...times).each do |i| a[(i*2)..(i*2+1)] = b end end_time = Time.now puts "その3:バイナリで入れ替え" puts "全体の時間:"+(end_time - start_time).to_s puts "1回あたり:"+((end_time - start_time)/times).to_s,""
結果
1000回
その1:+でつなげる 全体の時間:0.002042 1回あたり:2.042e-06 その2:UTF-8で入れ替え 全体の時間:0.001439 1回あたり:1.439e-06 その3:バイナリで入れ替え 全体の時間:0.001121 1回あたり:1.121e-06
10000回
その1:+でつなげる 全体の時間:0.078724 1回あたり:7.8724e-06 その2:UTF-8で入れ替え 全体の時間:0.039332 1回あたり:3.9332e-06 その3:バイナリで入れ替え 全体の時間:0.01164 1回あたり:1.164e-06
100000回
その1:+でつなげる 全体の時間:10.125697 1回あたり:0.00010125697 その2:UTF-8で入れ替え 全体の時間:2.943017 1回あたり:2.943017e-05 その3:バイナリで入れ替え 全体の時間:0.113457 1回あたり:1.13457e-06
+でつなげたのとUTF-8で入れ替えしたのは1回あたりの時間が順調に伸びた
それに比べて,バイナリでいれかえたのは1回あたりの入れ替えがほぼ変わらない
やっぱりバイナリが最速か・・・
面倒くさいけどRuby1.9.1で巨大な文字列を作成するときは
force_encoding("ASCII-8BIT")
をつけた方がいいみたい