根据this page,在c中计算整数绝对值(abs)而不进行分支的一种方法如下:
int v; // we want to find the absolute value of v
unsigned int r; // the result goes here
int const mask = v >> sizeof(int) * CHAR_BIT - 1;
r = (v + mask) ^ mask;出于好奇,我想将它与Python中的abs()函数进行比较:
> python -m timeit "v = -13" "r = abs(v)"
10000000 loops, best of 3: 0.119 usec per loop
> python -m timeit "v = -13" "mask = v >> 23" "r = (v + mask)^mask"
10000000 loops, best of 3: 0.18 usec per loop看起来abs()比按位操作有更好的性能。为什么?或者我在测试代码中遗漏了什么?
有关上述测试代码的更多信息:
由于v的大小,mask = v >> 23是通过24实现的。
发布于 2015-12-07 17:40:05
IPython笔记本简化了计时。紧跟在%%timeit之后的所有代码都是设置代码。我还把任务交给了v:
%%timeit v = -13
abs(v)
10000000 loops, best of 3: 94.8 ns per loop
%%timeit v = -13;mask = v >> 23
(v + mask)^mask
1000000 loops, best of 3: 182 ns per loop看起来abs的速度真的快了一倍。
查看字节码可以帮助了解正在发生的事情:
import dis对于abs
dis.dis("""
v = -13
r = abs(v)""")
2 0 LOAD_CONST 2 (-13)
3 STORE_NAME 0 (v)
3 6 LOAD_NAME 1 (abs)
9 LOAD_NAME 0 (v)
12 CALL_FUNCTION 1 (1 positional, 0 keyword pair)
15 STORE_NAME 2 (r)
18 LOAD_CONST 1 (None)
21 RETURN_VALUE对于另一种方法:
dis.dis("""
v = -13
mask = v >> 23
r = (v + mask)^mask
""")
2 0 LOAD_CONST 3 (-13)
3 STORE_NAME 0 (v)
3 6 LOAD_NAME 0 (v)
9 LOAD_CONST 1 (23)
12 BINARY_RSHIFT
13 STORE_NAME 1 (mask)
4 16 LOAD_NAME 0 (v)
19 LOAD_NAME 1 (mask)
22 BINARY_ADD
23 LOAD_NAME 1 (mask)
26 BINARY_XOR
27 STORE_NAME 2 (r)
30 LOAD_CONST 2 (None)
33 RETURN_VALUEhttps://stackoverflow.com/questions/34130143
复制相似问题