Скорость заданной операции пересечения, по-видимому, зависит от количества пересекающихся элементов.
Ваш целочисленный код создания создает значительно большее количество пересекающихся элементов, возможно, потому что он выбирает 2000 записей из меньшегоset (1000).
Например, в одном тесте 755 из 857 записей в i1 были продублированы в i2, но только 2 из 849 записей в w1 были продублированы в w2.
Когда я запустил простое изменение:
755.times {|x| w2 << w1.to_a[x]}
(сброс 755 элементов в w2, которые, как известно, находятся в w1), результаты в моей системе показали, что операция набора строк была намного ближе к эквивалентной операции целого числа.
Мои исходные результаты были:
1.9.2p180 :006 > t=Time.now;(0..1000).each {|i| w1 & w2};Time.now-t
=> 1.020355
1.9.2p180 :007 > t=Time.now;(0..1000).each {|i| i1 & i2};Time.now-t
=> 2.057535
Мои результаты после того, как два набора наборов стали более похожими с точки зрения пересекающихся элементов, были получены через:
1.9.2p180 :051 > 755.times {|x| w2 << w1.to_a[x]}
1.9.2p180 :052 > w2 = w2.to_a[-849..-1].to_set
:
1.9.2p180 :053 > t=Time.now;(0..1000).each {|i| w1 & w2};Time.now-t
=> 2.014967
1.9.2p180 :054 > t=Time.now;(0..1000).each {|i| i1 & i2};Time.now-t
=> 2.037542
1.9.2p180 :055 > [i1.length, i2.length, w1.length, w2.length, (i1 & i2).length, (w1 & w2).length]
=> [857, 884, 849, 849, 755, 754]
Надеюсь, это поможет некоторым;эти два момента времени находятся в пределах того, что я бы посчитал допустимым пределом погрешности, что другие вещи в системе могут вызывать разницу.Они, по сути, равны для строк такой длины.