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 doubles.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With