Consider the following code:
#include <cmath>
#include <cstdio>
const int COUNT = 100000000;
int main()
{
double sum = 0;
for (int i = 1; i <= COUNT; ++i)
sum += sqrt(i);
printf("%f\n", sum);
return 0;
}
It runs 5.5s on my computer. However, if I change sqrt
into std::sqrt
, It will run only 0.7s.
I know that if I use sqrt
, I'm using the function from C library, and if I use std::sqrt
, I'm using the one in <cmath>
.
But <cmath>
doesn't define one for int
, and if I change the type of i
into double
, they will run for equal speed. So the compiler isn't optimizing for int
. This seems to only happen to sqrt
in Windows.
So why is std::sqrt
much faster than sqrt
, but not other functions? And why in Linux they are not?
This is the typical situation in which the -fdump-tree-*
switch can give some insight into what is going on:
g++ -fdump-tree-optimized example1.cc
and you get the example1.cc.165t.optimized
file. Somewhere inside:
<bb 3>:
_5 = (double) i_2;
_6 = sqrt (_5);
sum_7 = sum_1 + _6;
i_8 = i_2 + 1;
The compiler (gcc v4.8.3) is doing the math with double
s.
Replacing sqrt
with std::sqrt
what you get is:
<bb 3>:
_5 = std::sqrt<int> (i_2);
sum_6 = sum_1 + _5;
i_7 = i_2 + 1;
Now it uses a different sqrt overload for integers (i_2
is int
and sum_6
is double
).
As Mike Seymour says in a comment, GCC uses the new overload whether or not you specify C++11.
Anyway under Linux there isn't a sensible performance difference between the two implementations.
Under Windows (MinGW) this is different since sqrt(double)
calls into msvcrt
.
来源:https://stackoverflow.com/questions/26547095/why-sqrt-in-global-scope-is-much-slower-than-stdsqrt-in-mingw