Issue #6177 has been updated by Glass_saga (Masaki M.).
File patch2.diff added
Nobuyoshi N. wrote:
先頭だけではなく、同一オブジェクトかどうかを常に先に調べるようにするとどうなるでしょうか。
最初の要素だけobject_idに依らない同値性の判定が必要なケース(先に添付したpatch.diffを適用したrubyにとって最悪のケース)を加えてベンチマークを取りました。
patch1は先に添付したpatch.diffを適用したもので、patch2は同一オブジェクトかどうかを常に先に調べるようにしたものです。
require ‘benchmark’
A = Array.new(100_0000){|n| n }
B = Array.new(1_0000){|n| n.to_s }
C = Array.new(1_0000){|n| n.to_s }
Benchmark.bm do |x|
x.report do
A == A.dup
end
x.report do
B == C
end
A.unshift(“hoge”)
D = A.dup
D[0] = “hoge”
x.report do
A == D
end
end
trunk(r35092):
user system total real
0.010000 0.000000 0.010000 ( 0.011911)
0.000000 0.000000 0.000000 ( 0.002002)
0.000000 0.000000 0.000000 ( 0.011341)
patch1:
user system total real
0.000000 0.000000 0.000000 ( 0.002591)
0.000000 0.000000 0.000000 ( 0.002391)
0.010000 0.010000 0.020000 ( 0.011916)
patch2:
user system total real
0.000000 0.000000 0.000000 ( 0.002261)
0.010000 0.000000 0.010000 ( 0.002306)
0.010000 0.000000 0.010000 ( 0.002829)
patch1では先頭でobject_idに依らない同値性の判定が必要になるとtrunkと同程度に遅くなってしまいますが、
patch2ではそのような場合でも高速に動作しました。
patch2のdiffを添付します。
Feature #6177: array.cのrb_ary_equal()の高速化
Author: Glass_saga (Masaki M.)
Status: Open
Priority: Normal
Assignee:
Category: core
Target version: 2.0.0
できる限りVALUEの値の比較のみに留め、必要になったらrb_equal()を用いるという方針でrb_ary_equal()の高速化を試みました。
次のベンチマークを行ったところ、以下のような結果となりました。
require ‘benchmark’
A = Array.new(100_0000){|n| n }
B = Array.new(1_0000){|n| n.to_s }
C = Array.new(1_0000){|n| n.to_s }
Benchmark.bm do |x|
x.report do
A == A.dup
end
x.report do
B == C
end
end
trunk(r35092):
user system total real
0.010000 0.000000 0.010000 ( 0.011711)
0.010000 0.000000 0.010000 ( 0.002169)
proposal:
user system total real
0.000000 0.000000 0.000000 ( 0.002257)
0.000000 0.000000 0.000000 ( 0.002307)
Fixnumのみで構成されたArrayの比較は従来の5倍ほどの速さになりました。
一方、rb_equal()による同値性の判定が必要となる場合でも性能の低下はありません。
patchを添付します。