2016-01-09 53 views
12

Ben array.min yavaş görünüyor fark, bu yüzden kendi naif uygulanması karşı bu test yaptım:Neden array.min çok yavaş?

require 'benchmark' 
array = (1..100000).to_a.shuffle 

Benchmark.bmbm(5) do |x| 
    x.report("lib:") { 99.times { min = array.min } } 
    x.report("own:") { 99.times { min = array[0]; array.each { |n| min = n if n < min } } } 
end 

sonuçları:

Rehearsal ----------------------------------------- 
lib: 1.531000 0.000000 1.531000 ( 1.538159) 
own: 1.094000 0.016000 1.110000 ( 1.102130) 
-------------------------------- total: 2.641000sec 

      user  system  total  real 
lib: 1.500000 0.000000 1.500000 ( 1.515249) 
own: 1.125000 0.000000 1.125000 ( 1.145894) 

Şok oldum. Kendi uygulamamın each aracılığıyla bir bloğu nasıl çalıştırabilmesi, yerleşik girişi nasıl yenebilir? Ve o kadar çok yendi?

Bir şekilde yanlış mıyım? Yoksa bu bir şekilde normal mi? Kafam karıştı.

Benim Yakut versiyonu, Pro, Windows 8.1 üzerinde çalışan


:

C:\>ruby --version 
ruby 2.2.3p173 (2015-08-18 revision 51636) [i386-mingw32] 
+0

Sonuçlarim oldukça farklı https://gist.github.com/weppos/3411eafc2c52e69ec751 –

+0

Yani sizin için eşit derecede hızlılar. Hala beni şaşırtıyor. Hangi versiyona sahipsin? 2.2.2p95'im var, şimdi 2.3'e yükselecek ve tekrar test edeceğim. –

+0

Elbette 2.2.3. Bunu şimdi yaptım ama yine de aynı şeyi gözlemliyorum. –

cevap

2

Enumerable#min'un uygulamasına bir göz atın. Sonunda elemanlar arasında geçiş yapmak ve min öğeyi almak için each kullanabilir, ancak daha önce birden fazla öğe döndürüp döndürmeyeceğini veya öğelerin bir geçiş bloğuyla karşılaştırılması gerekip gerekmediğini görmek için bazı ek kontroller yapar. Durumunuzda elemanlar min_i fonksiyonu ile karşılaştırılacak ve hız farkının nereden geldiğinden şüpheleniyorum - bu fonksiyon sadece iki sayıyı karşılaştırmaktan daha yavaş olacaktır.

Diziler için ek bir optimizasyon yoktur, tüm numaralar aynı şekilde çaprazlanır.

+0

Teşekkürler. Muhtemelen derlemiş olan C'nin muhtemelen benim yorumlanmamılan Ruby'den çok daha hızlı olmasını beklerdim. Ama buna bakarak 'min_i' fonksiyonunu görüyorum OPTIMIZED_CMP (i, memo-> min, memo) <0', ve eğer kendi uygulamamı değiştirmek için 'min = n if (n <=> dk.) <0', En azından yerleşik olandan * daha yavaş * olur (testimde yaklaşık% 8). Sanırım bu işi bırakacağım ve eğer hızlı bir şekilde istersem, kendimi "uzun" yolumla yapmalıyım. –

1

kullanırsanız Hatta daha hızlı:

def my_min(ary) 
    the_min = ary[0] 
    i = 1 
    len = ary.length 
    while i < len 
    the_min = ary[i] if ary[i] < the_min 
    i += 1 
    end 
    the_min 
end 

NOT

bildiğim bu değil Bir cevap, ama ben paylaşmaya değer olduğunu düşündüm ve bu kodu bir yorum woul koyarak d son derece çirkin oldu.

İlgili konular