问题源于这样一道作业题:
作业中提到的的那个invSqrt的代码如下:
float Q_rsqrt( float number )
{
long i;
float x2, y;
const float threehalfs = 1.5F;
x2 = number * 0.5F;
y = number;
i = * ( long * ) &y; // evil floating point bit level hacking
i = 0x5f3759df - ( i >> 1 ); // what the fuck?
y = * ( float * ) &i;
y = y * ( threehalfs - ( x2 * y * y ) ); // 1st iteration
// y = y * ( threehalfs - ( x2 * y * y ) ); // 2nd iteration, this can be removed
return y;
}
然后就自己写了个比较性能和精度的程序:
#include<stdio.h>
#include<math.h>
#include<time.h>
float Q_rsqrt(float number) //从wiki上获取的源代码
{
long i;
float x2, y;
const float threehalfs = 1.5F;
x2 = number * 0.5F;
y = number;
i = *(long *)&y; // evil floating point bit level hacking
i = 0x5f3759df - (i >> 1); // what the fuck?
y = *(float *)&i;
y = y * (threehalfs - (x2 * y * y)); // 1st iteration
y = y * (threehalfs - (x2 * y * y)); // 2nd iteration, this can be removed
return y;
}
int main()
{
int LoopCount = 1000000; //循环计算次数
float dur = 0; //时间间隔,初始化为0
float x; //待计算数
printf("Please input a number:"); //输入提示
scanf_s("%f", &x, sizeof(float));
float y;
clock_t t1 = clock();
for (int i = 0; i < LoopCount; i++) {
y =(float)( 1 / sqrt(x));
}
t1 = clock() - t1;
printf("1/sqrt(%f)=%f\n", x, y);
printf("%ld\n", t1);
printf("Use Time_1:%.10f s\n", ((float)t1 / CLOCKS_PER_SEC));
float z;
clock_t t2 = clock();
for (int j = 0; j < LoopCount; j++) {
z = Q_rsqrt(x);
}
t2 = clock() - t2;
printf("Q_rsqrt(%f)=%f\n", x, z);
printf("%ld\n", t2);
printf("Use Time_2:%.10f s\n", ((float)t2 / CLOCKS_PER_SEC));
getchar();
getchar();
return 0;
}
之后,出现了一个很奇怪的问题:
是的。。。C中的库函数效率基本上是下面那个算法的4倍!!!
但是,如果用C++中的库函数:
#include<stdio.h>
#include<cmath>
#include<time.h>
float Q_rsqrt(float number) //从wiki上获取的源代码
{
long i;
float x2, y;
const float threehalfs = 1.5F;
x2 = number * 0.5F;
y = number;
i = *(long *)&y; // evil floating point bit level hacking
i = 0x5f3759df - (i >> 1); // what the fuck?
y = *(float *)&i;
y = y * (threehalfs - (x2 * y * y)); // 1st iteration
y = y * (threehalfs - (x2 * y * y)); // 2nd iteration, this can be removed
return y;
}
int main()
{
int LoopCount = 1000000; //循环计算次数
float dur = 0; //时间间隔,初始化为0
float x; //待计算数
printf("Please input a number:"); //输入提示
scanf_s("%f", &x, sizeof(float));
float y;
clock_t t1 = clock();
for (int i = 0; i < LoopCount; i++) {
y =( 1 / sqrt(x));
}
t1 = clock() - t1;
printf("1/sqrt(%f)=%f\n", x, y);
printf("%ld\n", t1);
printf("Use Time_1:%.10f s\n", ((float)t1 / CLOCKS_PER_SEC));
float z;
clock_t t2 = clock();
for (int j = 0; j < LoopCount; j++) {
z = Q_rsqrt(x);
}
t2 = clock() - t2;
printf("Q_rsqrt(%f)=%f\n", x, z);
printf("%ld\n", t2);
printf("Use Time_2:%.10f s\n", ((float)t2 / CLOCKS_PER_SEC));
getchar();
getchar();
return 0;
}
然后跑出来的结果是这样的:
因此。。。似乎C的效率比C++高了很多很多?现在在VS2015中的实现就连那个神奇的快速算法也比不过了?(还是。。。我这样的比较是不对的。。。)
疑惑中。。。
伊谢尔伦2017-04-17 13:35:02
凡是涉及效率比較的問題,首先要確定的幾個前提條件是:
是否使用了相同的編譯器
是否使用了同樣編譯開關(例如最佳化開的是O幾)
是否在同樣的環境配置下運作的
運行的結果是否精確定量可重複
在上述條件都確定以後,才能確認結果的可靠性,然後再考慮結果產生的原因。
不知道題主的問題是否考慮了上述前提條件。
題目中只測試了兩個演算法在同一個 case 下的結果,也許這個 case 對於一個演算法是最優情況、對另一個演算法是最差情況,所以結果不能說明問題。例如對於一個一般情況下是O(n log n)複雜度的演算法,有可能最壞情況是O(n^2)、最優情況是O(n)。不能只憑一個 case 就說明某個演算法的優劣。