SORU
15 NİSAN 2010, PERŞEMBE


Ruby azalan bir dizi sıralama

Sağlamalarının aşağıdaki gibi bir dizi var

[
  { :foo => 'foo', :bar => 2 },
  { :foo => 'foo', :bar => 3 },
  { :foo => 'foo', :bar => 5 },
]

Her hash :bar değerine göre azalan şekilde yukarıda dizi sıralamak için çalışıyorum.

Dizi yukarıdaki sıralama aşağıdaki gibi sort_by kullanıyorum.

a.sort_by { |h| h[:bar] }

Artan düzende sıralar dizi ancak yukarıda. Nasıl azalan sıralama yapabilirim?

Bir çözüm için şunları yapın:

a.sort_by { |h| -h[:bar] }

Ama bu negatif işareti uygun görünmüyor. Herhangi bir görüş?

CEVAP
16 NİSAN 2010, Cuma


Her zaman çeşitli önerilen cevaplar üzerinde bir kıyaslama yapmak için çok aydınlatıcı oldu. Öğrendiğim şey şu:

#!/usr/bin/ruby

require 'benchmark'

ary = []
1000.times { 
  ary << {:bar => rand(1000)} 
}

n = 500
Benchmark.bm(20) do |x|
  x.report("sort")               { n.times { ary.sort{ |a,b| b[:bar] <=> a[:bar] } } }
  x.report("sort reverse")       { n.times { ary.sort{ |a,b| a[:bar] <=> b[:bar] }.reverse } }
  x.report("sort_by -a[:bar]")   { n.times { ary.sort_by{ |a| -a[:bar] } } }
  x.report("sort_by a[:bar]*-1") { n.times { ary.sort_by{ |a| a[:bar]*-1 } } }
  x.report("sort_by.reverse!")   { n.times { ary.sort_by{ |a| a[:bar] }.reverse } }
end

                          user     system      total        real
sort                  3.960000   0.010000   3.970000 (  3.990886)
sort reverse          4.040000   0.000000   4.040000 (  4.038849)
sort_by -a[:bar]      0.690000   0.000000   0.690000 (  0.692080)
sort_by a[:bar]*-1    0.700000   0.000000   0.700000 (  0.699735)
sort_by.reverse!      0.650000   0.000000   0.650000 (  0.654447)

@Pablo sort_by{...}.reverse! en ilginç bence. Test çalıştırmadan önce "-a[:bar]" ama değerini inkar, bir geçişte tüm diziyi tersine çevirmek için daha uzun sürer çıkıyor. daha yavaş olur diye düşündüm Çok bir fark yok, ama her hız, çok az yardımcı olur.


Lütfen bu sonuçlar Ruby 1.9 farklı olduğunu unutmayın

İşte Ruby 1.9 için sonuçlar.3p194 (2012-04-20 revizyon 35410) [x86_64-darwin10.8.0]:

                           user     system      total        real
sort                   1.340000   0.010000   1.350000 (  1.346331)
sort reverse           1.300000   0.000000   1.300000 (  1.310446)
sort_by -a[:bar]       0.430000   0.000000   0.430000 (  0.429606)
sort_by a[:bar]*-1     0.420000   0.000000   0.420000 (  0.414383)
sort_by.reverse!       0.400000   0.000000   0.400000 (  0.401275)

Bu MacBook Pro eski. Daha yeni, ya da daha hızlı makineler, daha düşük değerler olacaktır, ama göreli farklılıklar kalır.


İşte yeni donanım bit güncelleştirilmiş bir sürümünü ve Yakut 2.1.1 sürümü:

#!/usr/bin/ruby

require 'benchmark'

puts "Running Ruby #{RUBY_VERSION}"

ary = []
1000.times {
  ary << {:bar => rand(1000)}
}

n = 500

puts "n=#{n}"
Benchmark.bm(20) do |x|
  x.report("sort")               { n.times { ary.dup.sort{ |a,b| b[:bar] <=> a[:bar] } } }
  x.report("sort reverse")       { n.times { ary.dup.sort{ |a,b| a[:bar] <=> b[:bar] }.reverse } }
  x.report("sort_by -a[:bar]")   { n.times { ary.dup.sort_by{ |a| -a[:bar] } } }
  x.report("sort_by a[:bar]*-1") { n.times { ary.dup.sort_by{ |a| a[:bar]*-1 } } }
  x.report("sort_by.reverse")    { n.times { ary.dup.sort_by{ |a| a[:bar] }.reverse } }
  x.report("sort_by.reverse!")   { n.times { ary.dup.sort_by{ |a| a[:bar] }.reverse! } }
end

# >> Running Ruby 2.1.1
# >> n=500
# >>                            user     system      total        real
# >> sort                   0.670000   0.000000   0.670000 (  0.667754)
# >> sort reverse           0.650000   0.000000   0.650000 (  0.655582)
# >> sort_by -a[:bar]       0.260000   0.010000   0.270000 (  0.255919)
# >> sort_by a[:bar]*-1     0.250000   0.000000   0.250000 (  0.258924)
# >> sort_by.reverse        0.250000   0.000000   0.250000 (  0.245179)
# >> sort_by.reverse!       0.240000   0.000000   0.240000 (  0.242340)

Yukarıdaki kodu daha yeni bir Macbook üzerinde Ruby 2.2.1 kullanarak çalışan yeni sonuçları Pro. Yine, kesin sayı önemli değil, onların ilişkileri ile ilgili bir şey

Running Ruby 2.2.1
n=500
                           user     system      total        real
sort                   0.650000   0.000000   0.650000 (  0.653191)
sort reverse           0.650000   0.000000   0.650000 (  0.648761)
sort_by -a[:bar]       0.240000   0.010000   0.250000 (  0.245193)
sort_by a[:bar]*-1     0.240000   0.000000   0.240000 (  0.240541)
sort_by.reverse        0.230000   0.000000   0.230000 (  0.228571)
sort_by.reverse!       0.230000   0.000000   0.230000 (  0.230040)

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Adam Outler

    Adam Outler

    19 EKİM 2006
  • TopOfTheTech

    TopOfTheTech

    5 NİSAN 2010
  • Wii Minute Radio

    Wii Minute R

    31 Mayıs 2008