昨天我问question关于比较重叠的范围,从那时起它一直卡在我的喉咙里。
共识似乎是我的首选答案涉及使用数组交集运算符(&),效率低,因为比较数组的成本很高。
我想知道为什么这个功能在语言中?可能是语言创造者认为有时你需要一种优雅的方式来实现解决方案,即使这样做很昂贵吗?比较阵列是否太昂贵以至于应尽可能避免使用它?对我而言,Ruby的全部吸引力在于过早优化的语法优雅。
答案 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)