2011-07-15 25 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」第一