2013-03-03 13 views
8

Oto dwa proste bloki, które robią to samo:Dlaczego .index jest szybszy niż .all?

a = (0..100).to_a 

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

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

wyjątkiem, że drugi jest konsekwentnie trochę szybciej. Czemu?

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

Odpowiedz

5

Powodem jest to, że index jest metodą Array. Ruby będzie iterować (w C) nad przedmiotami i przekazywać je do bloku po kolei.

Z drugiej strony, all?, none?, one? (które wszystkie są o około 30% mniejsza) są metody Enumerable. Będą wywoływać each, co przyniesie do funkcji C, która przyniesie do bloku. Różnica w taktowaniu wynika z faktu, że są zaangażowane dwie jednostki: yield.

Należy zwrócić uwagę, że wyspecjalizowane wersje all? i in. można zdefiniować na Array, a uzyskałbyś tę samą wydajność co index, ale byłoby to trochę brzydkie i zbędne ...

1

To może być ze względu na dodatkowe kroku ! wykonanej w każdej przełomie iteracji z all?.

+0

Naprawdę? Z tą logiką 'x! = 1000' powinno być tak szybkie? –

+1

@LeeJarvis Pod warunkiem, że '! =' Jest zdefiniowany w C w podobnym algorytmie, jak zdefiniowano '==', to powinno być przewidywanie. – sawa

+2

Zmiana z '! (X == 1000)' na 'x! = 1000' nie ma znaczącej różnicy. –

Powiązane problemy