我最近不得不将整数的符号转换为-1或1
我想知道,通过if else语句或进行计算是否更快?
#if else#
s == -1 ? -1 : 1
#calculation#
ceil((s + 1) / 2) * 2 - 1
我知道这是一个非常简单的例子,但有时你需要绘制更大的间隔,直观地说,似乎数学会更快,以免较小的数学。
此外,相对速度如何受所用语言的影响(例如Python与C)。
答案 0 :(得分:4)
?
运算符会稍微快一点,因为它涉及的指令数量较少,而我们的日子处理器通常足够聪明,不会破坏管道,虽然它应该是这样的:
int r = (s < 0) ? -1 : 1;
括号内容清晰明了。
如果s
只能是-1,0或1,我建议:
int v[] = { -1, 1, 1 };
int r = v[s+1];
这永远不会破坏CPU管道。
答案 1 :(得分:1)
现代编译器并非愚蠢。例如,他们不会为有条件的动作做出愚蠢的不必要的跳跃。 (但这并不是说他们很聪明。)鉴于return x == -1 ? -1 : 1;
,Clang和GCC分别产生
sgn: # @sgn
cmp edi, -1
mov eax, 1
cmove eax, edi
ret
和
sgn:
xor eax, eax
cmp edi, -1
setne al
lea eax, [rax-1+rax]
ret
这些非常好,但我希望转变+ or
更快。 return (2 * -(x < 0)) + 1;
编译为
sgn: # @sgn
sar edi, 30
or edi, 1
mov eax, edi
ret
和
sgn:
mov eax, edi
sar eax, 31
or eax, 1
ret
分别。这些都非常快。
在CPython上也是如此,因为那是一名翻译。
答案 2 :(得分:0)
如果性能确实非常重要,我认为很难打败通过
在C语言中,你可以使用几个内联汇编语句来解决这个问题,具体取决于你的平台。
这可能会超过等效的三元条件(实际为s <= 0 ? -1 : 1
),因为不正确的分支分支预测将导致CPU转储管道。
通过这样的微优化,您需要使用分析来回答它,建立一个适当的测试框架并将性能测量到适当的统计显着性水平。
答案 3 :(得分:0)
在Python中,布尔运算符比数学运算快5倍:
%timeit (math.ceil((s + 1) / 2) * 2 - 1)
# 1000000 loops, best of 3: 381 ns per loop
%timeit (-1 if s < 0 else 1)
#10000000 loops, best of 3: 70.1 ns per loop
在Python中,您还可以使用直接字典查找,这几乎与布尔值一样好:
d = {-1:-1, 0:-1, 1:1}
%timeit d[s]
#10000000 loops, best of 3: 73.8 ns per loop