简体   繁体   中英

Is >0 faster than !=0 for an int?

Which test is faster : equality or inequality ?

For example, in a big while loop, should the condition be a>0 rather than a!=0 ?

When asking yourself a question about speed differences between different operators, use the timeit module to measure . They are equally fast:

>>> import timeit
>>> timeit.timeit('a > 0', 'a = 1', number=10**7)
0.2486400604248047
>>> timeit.timeit('a > 0', 'a = 0', number=10**7)
0.2411360740661621
>>> timeit.timeit('a != 0', 'a = 1', number=10**7)
0.24765801429748535
>>> timeit.timeit('a != 0', 'a = 0', number=10**7)
0.24990510940551758

That's the comparisons repeated 10 million times, and if you re-run the above tests you'll find the timings can vary somewhat and none are clear winners.

You should be focusing on readability here, not speed. A simple integer comparison is going to be an infinitesimal part of your overall execution speed, even in a loop.

If we're talking about a being an int , then on my machine at this very moment, an equality check is very slightly faster than a greater-than check. You can quickly check that yourself using the timeit module :

>>> for s in 'a = 2', 'a = 0', 'a = -2':
        timeit('a != 0', s)
        timeit('a > 0', s)

0.06030992519848155
0.06666935212976455
0.053299842422489974
0.06516424110179742
0.05866621696540619
0.06685335186756447

However , those numbers are super close to another. So you should only take one thing out of this answer: It does not matter .

These kind of things are micro optimizations. And micro optimizations very rarely have any impact on the real performance of an application. It is a lot more likely that there are thousand other parts in your application that have more impact on the performance to make this difference negligible. You should only care about such things if you actually profiled your application and confirmed that this part of your code is a bottleneck that is taking down the performance of your application. But for this particular code, I doubt that will ever be the case.

So please, don't bother about these minor difference but just use whatever makes more sense : Considering that these two checks have a different semantic meaning (a number being unequal to zero, or a number being larger than zero), choose the one that you actually meant to check for.

For me, timeit doesn't show any consistently noticeable difference (assuming you're working with integers)...

>>> timeit.timeit('1 > 0')
0.031796932220458984
>>> timeit.timeit('1 != 0')
0.03249096870422363
>>> timeit.timeit('1 > 0')
0.03250718116760254
>>> timeit.timeit('1 != 0')
0.031616926193237305

As stated in the comments on this question, rather than focusing on what operator is the fastest, you should focus on the one that makes the most sense. If you really mean "do this while a is greater than 0 " than use > . The amount of time spent doing this comparison is going to be a very minor contributor to your overall runtime, so it probably isn't worth worrying which operator is faster...

Is it the bottleneck of your program? Only if the answer is yes, you should be worried about it . Moreover, there is not something that says this will be sure faster in any OS, or with any type.


For fun, I timed the while loop:

#!/usr/bin/python
import time

a = 1000000
t0 = time.time()
while(a != 0):
    a = a - 1
t1 = time.time()

total = t1-t0
print total

and:

a > 0 gives:

0.12652015686

a != 0 gives:

0.111998081207


For timing, check this: How can I time a code segment for testing performance with Pythons timeit?


But , use timeit , as Martijn Pieters suggested ( Get time of execution of a block of code in Python 2.7 ), like this:

#!/usr/bin/python

import timeit
a = 1000000
start_time = timeit.default_timer()
while(a != 0):
    a = a - 1
elapsed = timeit.default_timer() - start_time
print elapsed

which gave for a > 0 :

0.10852098465

and for a != 0 :

0.108459949493

See the difference in the two timing approaches!

I think this somewhat leaden test program shows in the case of character and integer compares there is basically no difference

import string
def numericgtmostfail():
    for i in range(100):
        x= i > 99
    return x

def numericgtmostsucceed():
    for i in range(100):
        x= i > 1
    return x

def numericnemostsucceed():
    for i in range(100):
        x= i != 99
    return x

def numericnemostfail():
    for i in range(100):
        x= i != i
    return x

def chgtmostfail():
    for s in (string.lowercase * 4)[0:100]:
        x = s > 'y'
    return x

def chgtmostsucceed():
    for s in (string.lowercase * 4)[0:100]:
        x = s > 'a'
    return x

def chnemostfail():
    for s in (string.lowercase * 4)[0:100]:
        x = s != s 
    return x

def chnemostsucceed():
    for s in (string.lowercase * 4)[0:100]:
        x = s != 'a' 
    return x

if __name__ == '__main__':
    import timeit
    print(timeit.timeit("numericgtmostfail()", setup="from __main__ import numericgtmostfail"))
    print(timeit.timeit("numericgtmostsucceed()", setup="from __main__ import numericgtmostsucceed"))
    print(timeit.timeit("numericnemostsucceed()", setup="from __main__ import numericnemostsucceed"))
    print(timeit.timeit("numericnemostfail()", setup="from __main__ import numericnemostfail"))
    print(timeit.timeit("chgtmostfail()", setup="from __main__ import chgtmostfail"))
    print(timeit.timeit("chgtmostsucceed()", setup="from __main__ import chgtmostsucceed"))
    print(timeit.timeit("chnemostsucceed()", setup="from __main__ import chnemostsucceed"))
    print(timeit.timeit("chnemostfail()", setup="from __main__ import chnemostfail"))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM