Wow, odpowiedź @mu 無 rozwaliła mój umysł! Jednak ważne jest, aby nie generalizować podczas wyciągania wniosków ... Sprawdzasz czasy dla CONSTANTS nie zmiennych. W przypadku zmiennych mnożenie wydaje się wolniejsze niż porównanie.
Oto bardziej interesująca sprawa, w której numery porównywane są przechowywane w zmiennych rzeczywistych ...
import timeit
def go():
number=1000000000
print
print 'a>b, internal:',timeit.timeit(setup="a=1;b=1", stmt="a>b", number=number)
print 'a*b, internal:',timeit.timeit(setup="a=1;b=1", stmt="a*b", number=number)
print 'a>b, shell :',
%%timeit -n 1000000000 "a=1;b=1" "a>b"
print 'a*b, shell :',
%%timeit -n 1000000000 "a=1;b=1" "a*b"
go()
Wynik otrzymujemy:
a>b, internal: 51.9467676445
a*b, internal: 63.870462403
a>b, shell :1000000000 loops, best of 3: 19.8 ns per loop
a>b, shell :1000000000 loops, best of 3: 19.9 ns per loop
i porządek zostanie przywrócony w wszechświat;)
Dla kompletności, pozwala zobaczyć więcej przypadków ... A jeśli mamy jedną zmienną i jedną stałą?
import timeit
def go():
print 'a>2, shell :',
%%timeit -n 10000000 "a=42" "a>2"
print 'a*2, shell :',
%%timeit -n 10000000 "a=42" "a*2"
go()
a>2, shell :10000000 loops, best of 3: 18.3 ns per loop
a*2, shell :10000000 loops, best of 3: 19.3 ns per loop
co dzieje się z boolami?
import timeit
def go():
print
number=1000000000
print 'a==b : ', timeit.timeit(setup="a=True;b=False",stmt="a==b",number=number)
print 'a and b : ', timeit.timeit(setup="a=True;b=False",stmt="a and b",number=number)
print 'boolean ==, shell :',
%%timeit -n 1000000000 "a=True;b=False" "a == b"
print 'boolean and, shell :',
%%timeit -n 1000000000 "a=False;b=False" "a and b"
go()
a==b : 70.8013108982
a and b : 38.0614485665
boolean ==, shell :1000000000 loops, best of 3: 17.7 ns per loop
boolean and, shell :1000000000 loops, best of 3: 16.4 ns per loop
: D Teraz to jest interesujące wydaje logiczną i jest szybszy niż ==. Jednak wszystko to byłoby w porządku, ponieważ Donald Knuth nie straciłby snu, najlepszym sposobem porównania byłoby użycie i ...
W praktyce powinniśmy sprawdzić numpy, co może być jeszcze bardziej znaczące ...
import timeit
def go():
number=1000000 # change if you are in a hurry/ want to be more certain....
print '==== int ===='
print 'a>b : ', timeit.timeit(setup="a=1;b=2",stmt="a>b",number=number*100)
print 'a*b : ', timeit.timeit(setup="a=1;b=2",stmt="a*b",number=number*100)
setup = "import numpy as np;a=np.arange(0,100);b=np.arange(100,0,-1);"
print 'np: a>b : ', timeit.timeit(setup=setup,stmt="a>b",number=number)
print 'np: a*b : ', timeit.timeit(setup=setup,stmt="a*b",number=number)
print '==== float ===='
print 'float a>b : ', timeit.timeit(setup="a=1.1;b=2.3",stmt="a>b",number=number*100)
print 'float a*b : ', timeit.timeit(setup="a=1.1;b=2.3",stmt="a*b",number=number*100)
setup = "import numpy as np;a=np.arange(0,100,dtype=float);b=np.arange(100,0,-1,dtype=float);"
print 'np float a>b : ', timeit.timeit(setup=setup,stmt="a>b",number=number)
print 'np float a*b : ', timeit.timeit(setup=setup,stmt="a*b",number=number)
print '==== bool ===='
print 'a==b : ', timeit.timeit(setup="a=True;b=False",stmt="a==b",number=number*1000)
print 'a and b : ', timeit.timeit(setup="a=True;b=False",stmt="a and b",number=number*1000)
setup = "import numpy as np;a=np.arange(0,100)>50;b=np.arange(100,0,-1)>50;"
print 'np a == b : ', timeit.timeit(setup=setup,stmt="a == b",number=number)
print 'np a and b : ', timeit.timeit(setup=setup,stmt="np.logical_and(a,b)",number=number)
print 'np a == True : ', timeit.timeit(setup=setup,stmt="a == True",number=number)
print 'np a and True : ', timeit.timeit(setup=setup,stmt="np.logical_and(a,True)",number=number)
go()
==== int ====
a>b : 4.5121130192
a*b : 5.62955748632
np: a>b : 0.763992986986
np: a*b : 0.723006032235
==== float ====
float a>b : 6.39567713272
float a*b : 5.62149055215
np float a>b : 0.697037433398
np float a*b : 0.847941712765
==== bool ====
a==b : 6.91458288689
a and b : 3.6289697892
np a == b : 0.789666454087
np a and b : 0.724517620007
np a == True : 1.55066706189
np a and True : 1.44293071804
Znowu to samo zachowanie ... Więc myślę, można korzystać używając zamiast za == w ogóle,
przynajmniej w 2 Pythona (Python 2.4.1 2.7.11 | Anaconda (64-bitowy) | (domyślnie, 16 lutego 2016, 09:58:36) [MSC v.1500 64-bitowy (AMD64)]), gdzie wypróbowałem wszystkie te ...
Spodziewałem się wszystkich tych przykładów być nieustannie fałdowane na drodze do zostania kodowaniem bajtowym. Być może czas przeszkadza w tym. –
bardziej ogólnie, "ponieważ porównanie z 0 jest szybkie" jest bardzo istotne, jeśli programujemy Z80 lub coś podobnego ... inaczej to prawdopodobnie wcale nie jest, i jest to dokładnie to, o czym mówi pewna o wiele bardziej znana wypowiedź Knutha . Mogę się domyślać, że Knuth mówił tutaj o surowym języku asemblerowym, a jeśli tak, to próbując zastosować to do skompilowanego/interpretowanego języka, jest prawie całkowity non sequitur. –
Podczas testowania porównawczego należy uważać na [stałe składanie] (https://en.wikipedia.org/wiki/Constant_folding). – Schwern