计算开根号,为什么PC上查表还比sqrt()慢?
今天写了个程序测试开根号的速度,但结果让我很是不解,希望各位高手帮我解答一下。
#include <math.h>
#include <mmsystem.h>
float* makeSqrtTable()
{
int num;
float *tbl = (float *)malloc(sizeof(float) * (1000 + 1));
for (num = 0; num <= 100; num += 1)
{
tbl[num] = sqrt(num);
}
return tbl;
}
float tableSqrt(float *tbl, float num)
{
return tbl[(int)num];
}
void CMathTestDlg::OnCalc()
{
double result;
float* table=makeSqrtTable();
long count=100000;
int value=50;
DWORD start_time=timeGetTime();
for(int i=0;i<count;i++)
{
result=sqrt(value);
}
DWORD stop_time=timeGetTime();
DWORD all_time=stop_time-start_time;
start_time=timeGetTime();
for(i=0;i<count;i++)
{
result=tableSqrt(table,value);
}
stop_time=timeGetTime();
all_time=stop_time-start_time;
}
时间统计的结果查表比sqrt()慢,这是为什么?
[解决办法]
value一直不变,可能让编译器优化了 要看汇编代码才能确定
[解决办法]
开根号可以由以下三步实现
第一:求对数
第二:乘0.5
第三:求指数
其中第一步和第三步都可以由硬件电路实现,第二步的浮点数乘法看具体实现,最简情况下也就是浮点数指数位减1而已
相比之下,查表在理论上是线性时间,但如果表很大(精度要求越高则表越大,不用解释吧?),那么内存调度的时间就必须纳入考虑了
两者在理论上都是和数值大小无关的O(1)时间复杂度,哪个更快就取决于具体实现了
楼主的结果是否具有代表性不得而知,但原理上,“计算比查表更快”不是不可能的