代码之家  ›  专栏  ›  技术社区  ›  Gishu

Ruby中的数组排序怎么这么快?

  •  2
  • Gishu  · 技术社区  · 15 年前

    BitField Peter Cooper为同一主题编写的类。

    我一直在阅读Jon Bentley的编程珍珠,在尝试第一个示例之一时,它涉及位图排序-我需要一个位数组类型。我用了彼得的课

    class BitMapSort
      def self.sort(list, value_range_max)
        bitmap = BitField.new(value_range_max)
    
        list.each{|x| bitmap[x] = 1 }
    
        sorted_list = []
        0.upto(value_range_max-1){ |number|
          sorted_list << number if (bitmap[number] == 1)
        }
        sorted_list
      end
    end
    

                             user     system      total        real
    bitmap               11.078000   0.015000  11.093000 ( 11.156250)
    ruby-system-sort      0.531000   0.000000   0.531000 (  0.531250)
    quick-sort           21.562000   0.000000  21.562000 ( 21.625000)
    
    Benchmark.bm(20){|x|
        x.report("bitmap"){ ret = BitMapSort.sort(series, 10_000_000);}
        x.report("ruby-system-sort"){ ret = series.sort; }
        x.report("quick-sort"){ ret = QuickSort.sort( series, 0, series.length-1); }
        }
    

    ruby的默认排序比1M位域快22倍。在10M位向量上设置+1循环如何?Ruby中是否有更高效的位字段/数组?Ruby的默认排序是如何达到这种性能级别的。。是跳进C来完成这件事吗?

    5 回复  |  直到 9 年前
        1
  •  10
  •   levinalex    15 年前

    Array#sort 是用C实现的,请参见 rb_ary_sort array.c

    它还有一些检查来比较Fixnums,所以对整数数组进行排序甚至不需要方法查找。

        2
  •  7
  •   sepp2k    15 年前

    Ruby的默认排序是如何达到这种性能级别的。。是跳进C来完成这件事吗?

    ruby默认实现中的所有核心类和方法都是用C实现的。

        3
  •  2
  •   jonnii    15 年前

    它之所以快得多,可能是因为它是在C中的ruby实现中实现的。

        4
  •  2
  •   tadman    15 年前

    我认为这里真正的问题是你在做10万次比较,10万次数组获取,10万次很多事情,而一个经过适当优化的排序例程所做的操作要少得多,因为它处理的是一组固定的100万个项目。

    诸如sort之类的基本操作在Ruby虚拟机中得到了高度优化,用纯Ruby替代品很难打败它。

        5
  •  2
  •   John F. Miller    15 年前

    跳入C是完全正确的。为了提高性能,Array和Hash都有许多方法的C实现。整数和浮点文本也有一些棘手的代码优化。当您将它们转换为位图时,您也会失去这种优化。

    对于C或Java这样的编译语言,寻找复杂的优化模式是非常有意义的。对于解释型语言,解释每个命令的成本会适得其反。