在我最近花了一些时间在一个ruby项目中,我一直在计算两个大字符串集的交集。
根据我的理解,我决定比较整数而不是字符串是很有意义的(所有这些字符串都保存在数据库中,我可以很容易地将它们换成id)
当我真正做基准测试时,我发现完全相反。
首先,我生成了850个字符串集和约850个大整数集:

r = Random.new
w1 = (1..850).collect{|i| w="";(0..3).collect{|j| (rand*26 + 10).to_i.to_s(35)}.each{|l| w+=(l.to_s)};w}.to_set
w2 = (1..850).collect{|i| w="";(0..3).collect{|j| (rand*26 + 10).to_i.to_s(35)}.each{|l| w+=(l.to_s)};w}.to_set

i1 = (1..2000).collect{|i| (r.rand*1000).to_i**2}.to_set;
i2 = (1..2000).collect{|i| (r.rand*1000).to_i**2}.to_set;

然后我计时比较:
t=Time.now;(0..1000).each {|i| w1 & w2};Time.now-t
=> 0.301727
t=Time.now;(0..1000).each {|i| i1 & i2};Time.now-t
=> 0.70151

我觉得这太疯狂了!我一直认为整数比较要快得多。
所以我想知道,在栈的世界里,是否有人知道为什么ruby中的字符串比较要快得多,我真的很想听听你的想法。

最佳答案

设置相交操作的速度似乎受相交元素的数量影响。
整数创建代码正在创建大量相交元素,可能是因为它从较小的集合(1000)中选择了2000个条目。
例如,在一个测试中,i1中的857个条目中有755个在i2中重复,但w1中的849个条目中只有2个在w2中重复。
当我做一个简单的改动时:

755.times {|x| w2 << w1.to_a[x]}

(将755个已知位于w1中的项转储到w2中),系统上的结果显示字符串集操作更接近等效的整数操作。
我最初的结果是:
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]

我希望这对某些人有所帮助;这两次计时在我认为的误差范围内,系统上的其他东西可能会导致差异。基本上,对于这种长度的字符串,它们是相等的。

10-08 03:03