我很想知道。例如,如果我想检查一个数字是否是偶数,则其中任何一个都可以工作:
# values are True if even, False if odd
even_masked = not (number & 0x1)
even_modulo = (number%2 == 0)
它们都做同样的事情,但第一种方法在时钟周期方面要快得多。在C中你可以设置编译器为你做这样的优化,但Python解释器是否做了类似的事情?
答案 0 :(得分:0)
由于dis
模块:
>>> def test(number):
... even_masked = not (number & 0x1)
...
>>> def test2(number):
... even_modulo = (number%2 == 0)
...
>>> dis.dis(test)
2 0 LOAD_FAST 0 (number)
3 LOAD_CONST 1 (1)
6 BINARY_AND
7 UNARY_NOT
8 STORE_FAST 1 (even_masked)
11 LOAD_CONST 0 (None)
14 RETURN_VALUE
>>> dis.dis(test2)
2 0 LOAD_FAST 0 (number)
3 LOAD_CONST 1 (2)
6 BINARY_MODULO
7 LOAD_CONST 2 (0)
10 COMPARE_OP 2 (==)
13 STORE_FAST 1 (even_modulo)
16 LOAD_CONST 0 (None)
19 RETURN_VALUE
但是......我们可以看到两种方法之间的区别很小:
>>> timeit.timeit("even_modulo = (number%2 == 0)", setup="number=1", number=100000000)
11.886679887771606
>>> timeit.timeit("even_masked = not (number & 0x1)", setup="number=1", number=100000000)
11.225641965866089
因此,请保持脚本可读,而不是进行此类优化。理解第一行的时间将比执行中节省的时间更重要,即使您的脚本被使用了数百万次: - )
答案 1 :(得分:0)
dis
模块显示了Python所做的说明
not (number & 0x1)
:
0 LOAD_GLOBAL 0 (number)
3 LOAD_CONST 1 (1)
6 BINARY_AND
7 UNARY_NOT
8 POP_TOP
(number%2 == 0)
:
0 LOAD_GLOBAL 0 (number)
3 LOAD_CONST 1 (2)
6 BINARY_MODULO
7 LOAD_CONST 2 (0)
10 COMPARE_OP 2 (==)
13 POP_TOP
你给它的表达看起来很文字。