慢Ruby用于简单的数组操作

时间:2015-07-19 19:36:00

标签: ruby performance

我在Ruby中创建了简单的插入排序实现,遵循Cormen的“算法简介”中的伪代码:

def sort_insert(array)
  (1 ... array.length).each do |item_index|
    key = array[item_index]
    i = item_index - 1

    while i >= 0 && array[i] > key do
      array[i + 1] = array[i]
      i -= 1
    end
    array[i + 1] = key
  end
  array
end

它有效,但执行速度非常慢。对于~20k元素数组array = ((0..10_000).to_a * 2).shuffle,排序大约需要20秒。我只测量此方法调用的时间,没有数据准备等。在JavaScript中,一个非常类似的解决方案需要大约1秒。为什么Ruby(v.2.2.2p95)在这里这么慢?

编辑: 这个排序的JS版本,我用它:

function SortMethods() {
}

SortMethods.prototype.sortInsert = function(array) {
  for(let itemIndex = 1; itemIndex < array.length; itemIndex++) {
    let key = array[itemIndex];
    let i = itemIndex - 1;

    while( i >= 0 && array[i] > key) {
      array[i + 1] = array[i];
      i--;
    }
    array[i + 1] = key;
  }

  return array;
}

1 个答案:

答案 0 :(得分:0)

我不同意你的问题的前提 - Ruby在我的机器上提供的不仅仅是令人尊敬的性能。

为了说明这一点,我创建了一个包含100k随机数的文件:

$ ruby -e '100_000.times {printf "%22.20f\n", rand}' > rand100k.csv

然后我使用系统排序实用程序对此进行了排序,保存结果以供以后比较(作为正确性检查):

$ time sort -n < rand100k.csv > foo

real    0m0.067s
user    0m0.056s
sys     0m0.011s

我写了一个快速排序算法(当子列表大小变得足够小时翻转到插入排序)在纯ruby中,运行它,保存结果,并对系统排序输出和ruby输出文件进行区分:< / p>

$ time ruby quicksort_w_insertion.rb < rand100k.csv > bar

real    0m0.546s
user    0m0.537s
sys 0m0.008s
$ diff foo bar
$

正如您所看到的,两个排序运行产生相同的输出,并且非常快。在我看来,一个纯粹的Ruby程序只比相应的系统实用程序慢8到10倍,速度非常快。

这些运行是在MacBook Pro上使用ruby 2.2.2p95 (2015-04-13 revision 50293) [x86_64-darwin14]进行的。