Performance c+中哪个更快+;11:max(a-b,b-a)还是abs(a-b)?
在c++11中,哪个更快:Performance c+中哪个更快+;11:max(a-b,b-a)还是abs(a-b)?,performance,c++11,hardware,Performance,C++11,Hardware,在c++11中,哪个更快:max(a-b,b-a)还是abs(a-b)?我猜: 最大值: abs: 与0比较比比较两个值更简单 因此,我想告诉大家,abs更快,因为a、b是原始数据类型对于所有与性能相关的问题,只有一个真正的答案。 你需要在你的平台上,在你的用例上计时。 不同的stl实现也可以以不同的方式实现这些功能,在这种情况下,您的CPU体系结构也起着很大的作用 测量一下,然后得出你自己的结论。我打赌你不会真的注意到任何显著的差异。不过,我对您的用例很好奇,为什么这对您如此重要?时间,作为一
max(a-b,b-a)
还是abs(a-b)
?我猜:
最大值:
abs:
与0比较比比较两个值更简单
因此,我想告诉大家,
abs
更快,因为a、b
是原始数据类型对于所有与性能相关的问题,只有一个真正的答案。
你需要在你的平台上,在你的用例上计时。
不同的stl实现也可以以不同的方式实现这些功能,在这种情况下,您的CPU体系结构也起着很大的作用
测量一下,然后得出你自己的结论。我打赌你不会真的注意到任何显著的差异。不过,我对您的用例很好奇,为什么这对您如此重要?时间,作为一种度量标准,只有在变化的环境中才真正有用。在这里,您希望通过计算在较短的时间内发生变化,但最终可能发生的最重要的状态变化是我们自身。生命其实只是经历时间(最终是经历变化),它往往比我们希望的要短。我们只能在有限的时间内经历如此多的变化,因为有限的时间意味着有限的变化 因此,我建议这里最有效的解决方案是使用分析器,事后来看,在您以尽可能简单的方式编写代码之后(直到您有充分的理由不这样做)。抓取一个分析器并养成测量的习惯可能是在最短的时间内发生的最有效的状态变化,以实现更高效的计算。到目前为止,这将是最有效的解决方案 以下是杰西卡·阿尔巴的照片,以说明:
您可以使用
godbolt.org
,永久链接:
显然,对于随机数,
cstdlib
中的abs
会更快。这是一个毫无意义的问题。根据类型、编译器和平台的不同,有很多方法可以结束这种情况。请信任您的编译器。请花时间担心整数溢出。如何定义max
?是来自
的std::max
?标记为“1比较[sic]”的东西隐藏了更多的操作,除非您希望abs成为一个基本体(有时这是一个公平的假设,但您似乎没有做到),为什么不a>b?a-b:b-a
?甚至a==b?a:(a>b?a-b:b-a)
。我使用max定义如下:max(x,y)=x>y?x:y
,然后我传递参数:x=a-b,y=b-a
,与abs(x)=x>0?x:-x
相同。当然,你已经把它缩短了,但这不会是我所期望的@vladon@maskacovnik所有这些差异都会被任何现代编译器优化掉。其他编译器生成的代码是不同的,可能会得出不同的结论。只有在实际使用范围内对代码进行计时,才能给出一个现实的答案。@dau\u所有编译器都在生成几乎相同的代码。我已经做了基准测试(使用谷歌基准测试),所有的变体都在2-3毫秒左右。对于一些指令来说,2-3毫秒似乎非常不相关。此外,如何运行测试也很重要,是否多次调用同一个函数?你会在abs1之后打abs2吗?在这种情况下,缓存未命中所需的时间将比这两个函数的计算时间都要长。@dau_sama Google benchmark连续运行同一个函数数百万次。无论如何,由于cpu时钟的分辨率和海森堡的测不准原理,这样一个小函数的基准将是不正确的。这就是我想说的。这是一个毫无意义的测试。同样,运行百万次相同的函数也不能反映问题的用例。如果您使用rtdsc(在x86上)获取时钟信号,并使用它,则CPU时钟是准确的。谷歌基准可能会有不同的做法。
2 substraction: a-b, b-a
1 comparation: a-b>b-a ? a-b : b-a
1 substraction: a-b
1 comparation a-b>0 ? a-b : -(a-b)
#include <algorithm>
#include <cstdlib>
int abs1(int a, int b) {
return abs(a-b);
}
int abs2(int a, int b) {
return std::max(a-b, b-a);
}
int abs3(int a, int b) {
return a > b ? a - b : b - a;
}
int abs4(int a, int b) {
return a == b ? a : (a > b ? a - b : b - a);
}
abs1(int, int): # @abs1(int, int)
subl %esi, %edi
movl %edi, %eax
negl %eax
cmovll %edi, %eax
retq
abs2(int, int): # @abs2(int, int)
movl %edi, %eax
subl %esi, %eax
subl %edi, %esi
cmpl %esi, %eax
cmovgel %eax, %esi
movl %esi, %eax
retq
abs3(int, int): # @abs3(int, int)
movl %esi, %eax
subl %edi, %eax
subl %esi, %edi
cmovlel %eax, %edi
movl %edi, %eax
retq
abs4(int, int): # @abs4(int, int)
movl %edi, %eax
subl %esi, %eax
jne .LBB3_2
movl %edi, %eax
retq
.LBB3_2:
jg .LBB3_4
subl %edi, %esi
movl %esi, %eax
.LBB3_4:
retq