2011-07-15 71 views

回答

17

我用uniq uniq的不同组合做了一点基准测试!分类和排序! 没有显著差异:

   user  system  total  real 
sort!.uniq!103.547000 0.172000 103.719000 (104.093750) 
uniq!.sort!100.437000 0.093000 100.530000 (100.859375) 
uniq.sort 100.516000 0.157000 100.673000 (101.031250) 
sort.uniq 103.563000 0.062000 103.625000 (103.843750) 

你可能不使用是一样的东西:

array = [1] 
array.uniq!.sort! 

uniq的!将导致零和排序!会抛出异常。

基准我用:

require 'benchmark' 
require 'date' 

TEST_LOOPS = 10_000 
ARRAY = [] 
1000.times{ 
    ARRAY << Date.new(1900 + rand(100), rand(11)+1, rand(27) + 1) 
} 
Benchmark.bm(10) {|b| 

    b.report('sort!.uniq!') { 
    TEST_LOOPS.times { 
     a = ARRAY.dup 
     a.sort! 
     a.uniq! 
    }   #Testloops 
    }    #b.report 

    b.report('uniq!.sort!') { 
    TEST_LOOPS.times { 
     a = ARRAY.dup 
     # uniq!.sort! not possible. uniq! may get nil 
     a.uniq! 
     a.sort! 
    }   #Testloops 
    }    #b.report 

    b.report('uniq.sort') { 
    TEST_LOOPS.times { 
     a = ARRAY.dup.uniq.sort 
    }   #Testloops 
    }    #b.report 

    b.report('sort.uniq') { 
    TEST_LOOPS.times { 
     a = ARRAY.dup.sort.uniq 
    }   #Testloops 
    }    #b.report 

} #Benchmark 
+0

感谢您提供基准测试和指出'.uniq!.sort!'的潜在问题' –

+0

这不是一个好的基准,因为p '.uniq.sort!'和'.sort!.uniq!'之间的性能差异高度依赖于被排序的数据。你一次又一次地测试同一个伪随机数组,所以如果它有很少的重复元素(我认为是这种情况),uniq的影响可以忽略不计。 – Max

+0

这也是在其他答案http://stackoverflow.com/a/21376982/676874。 (我会建议提问者接受其他答案)。 – knut

5

你做这件事的方式真的没有关系。我首先猜测uniq,因此它会导致通过数组进行排序的项目更少。所以你可以做

a=[3,3,3,3,6,7,1,1,1,1,3] 
a.uniq! 
a.sort! 
+2

我需要做的'array_name.uniq!的.sort!'?还是第一个'!'不必要? –

+1

第一!是不必要的,因为这意味着它正在取代你的原始数组。 uniq不必替换它,因为它传递了返回值进行排序!然后将用最终值替换原始数组。 –

+2

这是不正确的!您首先通过'uniq'获取副本,然后将此副本替换为'sort!'。所以,如果你想排序和制作uniq,你必须同时使用'uniq!'和'sort!'。在irb中试用它并用'equal?'测试。 – mliebelt

0

运行一个或另一个首先取决于你的应用程序的需求。

1)除非你有巨大的数组,否则首先运行一个最有意义的数组。你是否在其他地方使用了排序或唯一的数组?一个订单是否更符合您的应用程序的逻辑? 2)如果你有巨大的阵列,而且我的意思是根据真实的测量结果确定你的代码运行时间过长(array.sort!.uniq!),那么你可以尝试其他顺序并查看。如果你有很多重复,那么array.uniq!.sort!可能会稍微快一些。 3)如果你担心速度问题,你可能需要使用sort_by。例如见https://github.com/JuanitoFatas/fast-ruby/blob/master/code/enumerable/sort-vs-sort_by.rb

+0

这是一个'Date'数组,所以我没有定义这种排序(IE我只是运行'array_name.sort!'而没有'sort {如何排序}'''sort_by'仍然是一个如果是这样,我会传入'sort_b'y怎么样? –

+0

如果你使用_array.uniq!.sort!_,你可能会遇到一个异常,试试_ [1] .uniq!.sort!_ – knut

+0

True,'' Array#uniq!'返回'nil',如果数组已经是唯一的,但是'array.uniq.sort!'不会完成David所要求的。'array'将不会被排序。 –

7

事实上,这取决于从唯一值的数量。 在knut的例子中,起始集合可以包含1000个中最多365个唯一值,并且操作顺序似乎没有影响。

如果'uniq'显着减小了数组大小,那么首先运行它会有明显的优势。

A=[] 
10_000.times do 
    A << rand(80) 
end 

Benchmark.bm(10) do |b| 
    b.report "sort.uniq" do 
    10_000.times {A.sort.uniq} 
    end 
    b.report "uniq.sort" do 
    10_000.times {A.uniq.sort} 
    end 
end 

       user  system  total  real 
sort.uniq 20.202000 0.281000 20.483000 (20.978098) 
uniq.sort 9.298000 0.000000 9.298000 ( 9.355936) 

我没有测试'.uniq!.sort!'排列,但我相信他们应该遵循上述结果。

这个例子可能有些极端,但我不明白为什么人们不应该总是运行“.uniq”第一