为什么 < 比 >= 慢
我在用下面的代码进行测试,发现<这个操作比>=要慢,不知道为什么会这样?
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
7 个回答
5
你的第一个测试结果是对的,第二个测试结果是错的。可能因此会有一些细微的处理差别。
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);
}
所以在比较中,你能看到的变化就只有通过switch语句的不同路径,以及结果是True(真)还是False(假)。我猜测你看到的变化可能是因为CPU的执行路径(还有可能是分支预测),所以你观察到的效果在其他版本的Python中也可能会消失,或者正好相反。
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
代码几乎是一样的,但f1总是执行第15行,然后跳到第21行,而f2总是执行15 -> 18 -> 21。所以性能的影响应该是因为if语句中的真或假,而不是<或>=的问题。