为什么<慢于> =

Ili*_*iev 18 python optimization performance

我使用以下代码进行测试,似乎<慢于> =.,有谁知道为什么?

import timeit
s = """
  x=5
  if x<0: pass
"""
  t = timeit.Timer(stmt=s)
  print "%.2f usec/pass" % (1000000 * t.timeit(number=100000)/100000)
#0.21 usec/pass
z = """
  x=5
  if x>=0: pass
"""
t2 = timeit.Timer(stmt=z)
print "%.2f usec/pass" % (1000000 * t2.timeit(number=100000)/100000)
#0.18 usec/pass
Run Code Online (Sandbox Code Playgroud)

小智 32

在Python 3.1.2中,某些时候<比>更快.我尝试在反汇编程序中读取它,

import dis
def f1():
    x=5
    if x < 0: pass

def f2():
    x = 5
    if x >=0: pass

>>> dis.dis(f1)
  2           0 LOAD_CONST               1 (5) 
              3 STORE_FAST               0 (x) 

  3           6 LOAD_FAST                0 (x) 
              9 LOAD_CONST               2 (0) 
             12 COMPARE_OP               0 (<) 
             15 POP_JUMP_IF_FALSE       21 
             18 JUMP_FORWARD             0 (to 21) 
        >>   21 LOAD_CONST               0 (None) 
             24 RETURN_VALUE         
>>> dis.dis(f2)
  2           0 LOAD_CONST               1 (5) 
              3 STORE_FAST               0 (x) 

  3           6 LOAD_FAST                0 (x) 
              9 LOAD_CONST               2 (0) 
             12 COMPARE_OP               5 (>=) 
             15 POP_JUMP_IF_FALSE       21 
             18 JUMP_FORWARD             0 (to 21) 
        >>   21 LOAD_CONST               0 (None) 
             24 RETURN_VALUE         
Run Code Online (Sandbox Code Playgroud)

代码几乎相同,但f1总是运行第15行并跳转到21,f2总是运行15 - > 18 - > 21,因此在if语句中性能应该受到true/false的影响而不是<或> = problem.


djn*_*jna 5

您的第一个测试评估为true,第二个测试评估为false.也许结果处理略有不同.

  • 用`x = -5`运行测试似乎会逆转结果. (4认同)

Dun*_*can 5

COMPARE_OP操作码包含一个优化,其中两个操作数都是与C兼容的整数,在这种情况下,它只是与比较类型的switch语句进行内联比较:

if (PyInt_CheckExact(w) && PyInt_CheckExact(v)) {
        /* INLINE: cmp(int, int) */
        register long a, b;
        register int res;
        a = PyInt_AS_LONG(v);
        b = PyInt_AS_LONG(w);
        switch (oparg) {
        case PyCmp_LT: res = a <  b; break;
        case PyCmp_LE: res = a <= b; break;
        case PyCmp_EQ: res = a == b; break;
        case PyCmp_NE: res = a != b; break;
        case PyCmp_GT: res = a >  b; break;
        case PyCmp_GE: res = a >= b; break;
        case PyCmp_IS: res = v == w; break;
        case PyCmp_IS_NOT: res = v != w; break;
        default: goto slow_compare;
        }
        x = res ? Py_True : Py_False;
        Py_INCREF(x);
}
Run Code Online (Sandbox Code Playgroud)

因此,比较中唯一的变化是通过switch语句的路由以及结果是True还是False.我的猜测是你只是看到由于CPU的执行路径(也许是分支预测)引起的变化,所以你看到的效果可能很容易消失,或者在其他版本的Python中反过来.