为什么array.min这么慢?

时间:2016-01-09 15:31:12

标签: ruby performance min built-in

我注意到array.min似乎很慢,所以我针对自己的天真实施做了这个测试:

require 'benchmark'
array = (1..100000).to_a.shuffle

Benchmark.bmbm(5) do |x|
  x.report("lib:") { 99.times { min = array.min } }
  x.report("own:") { 99.times { min = array[0]; array.each { |n| min = n if n < min } } }
end

结果:

Rehearsal -----------------------------------------
lib:    1.531000   0.000000   1.531000 (  1.538159)
own:    1.094000   0.016000   1.110000 (  1.102130)
-------------------------------- total: 2.641000sec

            user     system      total        real
lib:    1.500000   0.000000   1.500000 (  1.515249)
own:    1.125000   0.000000   1.125000 (  1.145894)

我很震惊。如何通过each运行块的自己的实现击败内置?并且打败了这么多?

我有点错吗?或者这是不正常的?我很困惑。

我的Ruby版本,在Windows 8.1 Pro上运行:

C:\>ruby --version
ruby 2.2.3p173 (2015-08-18 revision 51636) [i386-mingw32]

3 个答案:

答案 0 :(得分:3)

查看Enumerable#min的实施情况。它最终可能会使用each循环遍历元素并获取min元素,但在此之前它会进行一些额外的检查以查看是否需要返回多个元素,或者是否需要通过一个元素来比较元素通过块。在你的情况下,元素将通过min_i函数进行比较,我怀疑速度差异来自哪里 - 该函数将比简单比较两个数字慢。

对阵列没有额外的优化,所有的枚举都以相同的方式遍历。

答案 1 :(得分:2)

如果你使用它会更快:

def my_min(ary)
  the_min = ary[0]
  i = 1
  len = ary.length
  while i < len
    the_min = ary[i] if ary[i] < the_min
    i += 1
  end
  the_min
end

注意

我知道这不是一个答案,但我认为值得分享并将此代码放入评论会非常难看。

答案 2 :(得分:1)

对于那些喜欢升级到较新版本软件的人

require 'benchmark'
array = (1..100000).to_a.shuffle

Benchmark.bmbm(5) do |x|
  x.report("lib:") { 99.times { min = array.min } }
  x.report("own:") { 99.times { min = array[0]; array.each { |n| min = n if n < min } } }
end

Rehearsal -----------------------------------------
lib:    0.021326   0.000017   0.021343 (  0.021343)
own:    0.498233   0.001024   0.499257 (  0.499746)
-------------------------------- total: 0.520600sec

            user     system      total        real
lib:    0.018126   0.000000   0.018126 (  0.018139)
own:    0.492046   0.000000   0.492046 (  0.492367)

RUBY_VERSION # => "2.7.1"

如果您想以真正高效的方式解决此问题:O(log(n))或O(n),请查看https://en.wikipedia.org/wiki/Selection_algorithm#Incremental_sorting_by_selectionhttps://en.wikipedia.org/wiki/Heap_(data_structure)