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

(Ruby)如果数组交集运算符(&;)效率低下,为什么可用?,ruby,arrays,intersection,Ruby,Arrays,Intersection,昨天我问了一个关于比较重叠范围的问题,从那以后我就一直在抱怨 大家的共识似乎是,我的首选答案是使用数组交集运算符(&),这是低效的,因为比较数组的成本很高 我想知道,为什么语言中会有这种功能?语言创造者是否会认为,有时你需要一种优雅的方式来实现一个解决方案,即使这样做很昂贵?比较阵列的成本是否太高,以至于您应该尽可能避免?Ruby对我的吸引力在于它注重语法的优雅,而不是过早的优化 昨天问题的措辞听起来像是在计算二进制条件:这些范围重叠吗?给出的答案可以在恒定的时间内计算出来,因此如果它们对你有用

昨天我问了一个关于比较重叠范围的问题,从那以后我就一直在抱怨

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


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

昨天问题的措辞听起来像是在计算二进制条件:这些范围重叠吗?给出的答案可以在恒定的时间内计算出来,因此如果它们对你有用,那么坚持它们是有意义的

如果您需要知道重叠的范围,,则&operator将是合适的,但这不是您要问的


至于它存在的原因,我只能推测:它不仅增加了便利性,而且不难想象通过语言环境可以优化数组连接操作的方式——即使在最坏的情况下,它的计算可能仍然需要线性或n*log(n)时间。(如果每个操作都必须有一个固定的时间结果,那么我们就必须去掉很多方法!)

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

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


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

Ruby中的数组是非类型化的:它们可以包含多种类型,包括散列、其他数组、符号等等。在类型化数组中,排序和比较要简单得多。比较非类型化集合(尤其是包含集合的集合)本质上成本更高。

就测试而言,这似乎并不太糟糕。机器为i7(2.0Ghz双核)


那么,我们应该关注使用大型阵列吗?好的,你说得很好-我从一个更高效的存储结构开始-一个范围-然后改用一个效率更低的结构。我只是怀疑我们是否应该如此关注这个优化。我不认为使用范围对象上可用的内容而不是进行(潜在的)昂贵的转换是过早的优化。MarkusQ的答案简单易读,一行,对任何大小范围都有效。是的,它便于查看重叠的程度,也便于直观地计算二进制条件。至少我觉得是这样。
#!/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)