红宝石:排序!和uniq!哪个先运行?

Dav*_*ill 14 ruby

我需要同时运行sort!,并uniq!在阵列上.先运行哪个更好?或者有没有办法将这些组合成一个命令?

knu*_*nut 18

我用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)
Run Code Online (Sandbox Code Playgroud)

您可能不会使用的是:

array = [1]
array.uniq!.sort!
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)


use*_*903 7

实际上,它取决于唯一值的数量.在knut的示例中,起始集可以包括最多360个中的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)
Run Code Online (Sandbox Code Playgroud)

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

这个例子可能有点极端,但我不明白为什么不应该首先运行'.uniq'


Mic*_*ile 5

你这样做的方式并不重要.我想首先是uniq所以它导致更少的项目进行排序,一次通过数组.所以你可以做到

 a=[3,3,3,3,6,7,1,1,1,1,3]
 a.uniq!
 a.sort!
Run Code Online (Sandbox Code Playgroud)

  • 我需要做`array_name.uniq!.sort!`?或者第一个`!`是不必要的? (2认同)
  • 那不是真的!你首先得到`uniq`的副本,然后这个副本被`sort!`取代.因此,如果你想对uniq进行排序和制作,你必须同时使用`uniq!`和`sort!`.在irb中试一试并用`equal?`进行测试. (2认同)
  • 你不应该结合uniq!并排序!按此顺序,它可能以例外结束.看看_ [1] .uniq!.sort!_ uniq会发生什么!返回nil并排序!将会抛出异常.当你第一次排序!然后你可以使用uniq!后记.或者你把它分成两个电话. (2认同)