gpt4 book ai didi

python - 如果 Python3 否定与 XOR 相比,为什么它运行得更快?

转载 作者:行者123 更新时间:2023-12-03 14:32:24 26 4
gpt4 key购买 nike

我想用 1 否定一个词或 XOR 一个词两者都应该占用处理器的 1 个时钟周期,但如果使用 Python3,以下代码来计算一个字的奇偶校验:

def parity(x: int) -> int:
p = 0
while x:
p = ~p
x = x & (x-1)
return p & 1

运行 10,000 个测试用例会报告 4μs平均运行时间始终如一,但如果是:
def parity(x: int) -> int:
p = 0
while x:
p = p ^ 1
x = x & (x-1)
return p

那么它始终是 5μs .它实际上最后少了一个操作,不需要 & 1 .

甚至
def parity(x: int) -> int:
p = 0
while x:
p += 1
x = x & (x-1)
return p % 2

一直在运行 4μs .为了测试增量与加法,我更改了 p += 1p += 7它再次始终是 4μs .使用 Python3 进行否定、增加或加法比 XOR 更快的原因是什么? (如果它有任何区别,它在Mac上)。

最佳答案

事实证明,在 Python 中,并非所有运算符都是平等创建的。

您在问题中提到了“时钟周期”。确实,典型的 CPU 可以在一个周期内完成许多这些任务,但是,Python 代码(在 CPython 中)的执行由编译后的字节码决定。这是一个操作(操作代码)列表,它们在 CPython 运行时中映射到 C 代码。

这些 C 代码部分的执行时间显然可能不同。事实上,您会发现它们都与“1 个周期”操作无关,而是与多个函数调用和分支语句相关联。

如果你反汇编你给出的 2 个函数,dis.dis(parity) ,您将在相关部分看到它们的操作码有何不同。

从第一个函数(否定)

10 LOAD_FAST                1 (p)
12 UNARY_INVERT
14 STORE_FAST 1 (p)

从第二个函数(异或):
10 LOAD_FAST                1 (p)
12 LOAD_CONST 2 (1)
14 BINARY_XOR
16 STORE_FAST 1 (p)

最值得注意的是, UNARY_INVERT改为 BINARY_XOR .查师傅 switch (opcode) { ... } 在 Python/ceval.c 中查看这些操作代码及其对应代码的不同之处。

这是一个小测试程序,用于比较 Python 中一些不同运算符的时间。

import timeit

print('binary operators')

ops = ['+', '-', '^', '&', '|']
for op in ops:
t = timeit.timeit(f'a = a {op} b', 'a = 1; b = 2')
print(op, t)

print('unary operators')

ops = ['-', '~', 'not']
for op in ops:
t = timeit.timeit(f'a = {op} a', 'a = 1')
print(op, t)

这是我在 CPython 3.7.2 64 位 (Windows) 中的结果
binary operators
+ 0.038782999999999956
- 0.03799190000000002
^ 0.05287609999999998
& 0.03716779999999997
| 0.0518267
unary operators
- 0.020763399999999987
~ 0.020213900000000007
not 0.01701140000000001

从这些结果来看,似乎 ^BINARY_XOR实际上是最慢的操作符(在那些测试中)

关于python - 如果 Python3 否定与 XOR 相比,为什么它运行得更快?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60518663/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com