2013-03-03 18 views
8

Qui ci sono due semplici blocchi che fanno la stessa cosa:Perché è .index più veloce di .all?

a = (0..100).to_a 

a.all? do |x| 
    !(x == 1000) 
end 

nil == a.index do |x| 
    x == 1000 
end 

eccezione del fatto che il secondo è sempre un po 'più veloce. Perché?

         user  system  total  real 
testing all      1.140000 0.000000 1.140000 ( 1.144535) 
testing index     0.770000 0.000000 0.770000 ( 0.769195) 

risposta

5

Il motivo è che index è un metodo di Array. Ruby esegue iterazioni (in C) sugli oggetti e li cede al blocco a sua volta.

D'altra parte, all?, none?, one? (che saranno tutti più lento circa il 30%), sono metodi di Enumerable. Chiameranno lo each, che si arrenderanno a una funzione C che arriverà al blocco. La differenza di tempo è dovuta al fatto che ci sono due yield coinvolti.

Si noti che le versioni specializzate di all? e altri. potrebbe essere definito su Array e si otterrebbe la stessa prestazione di index, ma sarebbe un po 'brutto e ridondante ...

1

Potrebbe essere a causa del passaggio aggiuntivo ! fatto in ogni turno dell'iterazione con all?.

+0

Davvero? Con quella logica 'x! = 1000' dovrebbe essere il più veloce? –

+1

@LeeJarvis A condizione che '! =' Sia definito in C in un algoritmo simile a come '==' è definito, quella dovrebbe essere la previsione. – sawa

+2

Cambiarlo da '! (X == 1000)' a 'x! = 1000' non fa una differenza significativa. –

Problemi correlati