(Ruby)如果数组交集运算符(&)效率低下,为什么它可用?

时间:2009-03-31 16:50:13

标签: ruby arrays intersection

昨天我问question关于比较重叠的范围,从那时起它一直卡在我的喉咙里。

共识似乎是我的首选答案涉及使用数组交集运算符(&),效率低,因为比较数组的成本很高。

我想知道为什么这个功能在语言中?可能是语言创造者认为有时你需要一种优雅的方式来实现解决方案,即使这样做很昂贵吗?比较阵列是否太昂贵以至于应尽可能避免使用它?对我而言,Ruby的全部吸引力在于过早优化的语法优雅。

4 个答案:

答案 0 :(得分:13)

&不是一种特别低效的方法。我认为你误解了对接受的答案的批评。

您首选的解决方案效率低下,因为它会将范围转换为数组。

1..10000等范围的内存占用量相对较小 - 它只存储起点和终点。但是如果将其转换为数组,则为所有10,000个条目分配内存。

答案 1 :(得分:4)

昨天的问题的措辞听起来像是在计算二元条件:这些范围是否重叠?给出的答案可以在恒定的时间内计算出来,所以如果它们适合你,那么坚持使用它们是有意义的。

&如果你需要知道重叠的范围,那么运算符是合适的,但这不是你所要求的。

至于它为什么存在,我只能推测:它不仅增加了方便性,而且不难想象语言环境可以优化数组连接操作的方式 - 即使它的计算可能在最坏的情况下仍需要线性或n * log(n)时间。 (如果每个操作都必须有一个恒定时间的结果,我们必须摆脱不少方法!)

答案 2 :(得分:0)

Ruby中的数组是无类型的:它们可以包含混合类型,包括哈希,其他数组,符号等等。在类型化数组中,排序和比较要简单得多。比较无类型集合(尤其是包含集合的集合)本质上更昂贵。

答案 3 :(得分:0)

在测试方面似乎并不太糟糕。机器是i7(2.0Ghz双核)

#!/bin/ruby
require 'benchmark'
n = []
1.upto(10_000_000) do |i|
  n << i
end

m = Array.new(1000000){ rand(10_000_000)+1 }

Benchmark.bm(10) do |x|
  x.report('array_intersection'){ n & m }
end

                    user     system      total        real
array_intersection  2.870000   0.040000   2.910000 (  2.895202)