我要提高10倍的力量很多次。
有比使用数学库pow(10,double)更有效的方法吗?如果有关系的话,我的双打在-5到-11之间总是负的。
我假设pow(double,double)使用比pow(10,double)更通用的算法,因此可能不是最快的方法。根据下面的一些答案,这可能是一个错误的假设。
至于其原因,则是逻辑插值。我有一张x和y值的表。我的对象有一个已知的x值(几乎总是一个双值)。
double Dbeta(struct Data *diffusion, double per){
double frac;
while(per>diffusion->x[i]){
i++;
}
frac = (per-diffusion->x[i-1])/(diffusion->x[i]-diffusion->x[i-1]);
return pow(10,log10DB[i-1] + frac * (log10DB[i]-log10DB[i-1]));
}这个函数被多次调用。我被告知要调查侧写,所以这是我首先要做的。
我刚刚被告知我可以用自然对数代替基数10,这显然是对的。(我的愚蠢有时甚至让我自己都感到惊讶。)
在用自然对数代替所有东西之后,一切都跑得更快了。通过分析(这是我今天学到的一个新单词),我发现我的代码中有39%花在了exp函数中,所以对于那些想知道这部分是否是阻碍我的代码的部分的人来说,是的。
发布于 2020-10-22 07:58:51
是的,pow函数是缓慢的(对于那些要求基准的人来说,大约是乘法成本的50倍)。
10^x = exp(log(10^x)) = exp(x * log(10))。
所以您可以用exp(x * M_LN10)实现10^x,这应该比pow.更有效。
如果双精度不重要,请使用函数
expf (或powf)的浮点版本,这应该比双重版本更有效。如果粗精度可以的话,在-5,-11范围内预先计算一个表,然后用线性interpolation.快速查找。
一些基准(使用glibc 2.31):
Benchmark Time
---------------------------------
pow(10, x) 15.54 ns
powf(10, x) 7.18 ns
expf(x * (float)M_LN10) 3.45 ns发布于 2020-10-22 07:53:43
对于pow(10.0, n)来说,设置c = log(10.0)应该更快,您可以计算一次,然后使用exp(c*n),它应该比pow(10.0, n)快得多(pow(10.0, n)基本上是在内部完成相同的事情,只不过是一遍又一遍地计算log(10.0),而不是一次)。除此之外,你可能没什么别的办法。
https://stackoverflow.com/questions/64477054
复制相似问题