是否可以优化此功能?

Ins*_*ere 17 java math optimization function

经过剖析后,我发现这种方法占用了大部分计算时间.我真的没有看到优化的方法,因为它是一个可怕的功能.(它是......)也许有人能给我一些好主意吗?

public static double perceivedLoudness(double L_G, double L_ETQ, double a0) {
  double t1 = 1d + 1 / 4d * Math.pow(10d, 0.1d * (L_G - a0 - L_ETQ));
  double t2 = Math.pow(t1, 0.25);
  return 0.064d * Math.pow(10, 0.025 * L_ETQ) * (t2 - 1);
 }
Run Code Online (Sandbox Code Playgroud)

这是改进版本:

public static double perceivedLoudness(double L_G, double L_ETQ, double a0) {
  double x = L_G - a0 - L_ETQ;
  double t1 = 0.25 * Math.exp(0.230259 * x) + 1;
  double t2 = Math.sqrt(Math.sqrt(t1));
  return ltqFactors[(int)L_ETQ]  * (t2 - 1);
 }
Run Code Online (Sandbox Code Playgroud)

对ltqFactors的查找就是这样的.ltqValues从给定的ltq函数中保持20个点,大约应该是足够的.

for( int i = 0; i < etqValues.length; ++i) {
  ltqFactors[(int)etqValues[i]] = 0.064d * Math.exp(etqValues[i] * 0.05756462732485114210d);
  }
Run Code Online (Sandbox Code Playgroud)

编辑:经过更多文件的测试运行后,我加速了~100%:

  • 旧:6,2%,有7000000个电话
  • 新增:3,2%8000000电话.

谢谢你到目前为止!

Edit2:我不知道接受哪个答案.:(与其他一些改进(主要是查找表)9000声音文件的处理时间从4:30min下降到3:28min.

我将保持这个问题,看看是否有其他想法,但接受一个答案.

编辑:我现在有点沮丧.我使用JFace树形浏览器让用户浏览结果,它需要更多的时间来更新计算本身.:/

Ale*_* C. 23

你的函数似乎是解析的,我建议用插值方法完全替换它.这样,您就可以减少对Math.Pow一些算术运算的昂贵调用.

在这种情况下,最好的应该是有理函数逼近.你的函数可能在复平面上有极点,这通常会使多项式插值失效.

请注意,您有两个变量:L_G - a0 - L_ETQL_ETQ.插值应仅在一个变量中执行.

我会去t2作为函数的有理函数逼近L_G - a0 - L_ETQ.看一下Numerical Recipes的实现技巧.

另外,对于最后一部分,替换

Math.pow(10, 0.025 * L_ETQ); 
Run Code Online (Sandbox Code Playgroud)

通过

Math.exp(L_ETQ * 0.05756462732485114210d)
Run Code Online (Sandbox Code Playgroud)

(这是exp(L_ETQ * 0.025 * log(10))).

所以你应该对一些算术运算和指数运算很好.

编辑: 查看t2作为函数的图表L_G - a0 - L_ETQ.

编辑:替换

double t1 = 1d + 1 / 4d * Math.pow(10d, 0.1d * (L_G - a0 - L_ETQ)); 
double t2 = Math.pow(t1, 0.25);
Run Code Online (Sandbox Code Playgroud)

通过

double x = L_G - a0 - L_ETQ;
double t1 = 0.25 * Math.exp(0.230259 * x) + 1;
double t2 = Math.sqrt(Math.sqrt(t1));
Run Code Online (Sandbox Code Playgroud)

而你应该获得更多%.在这一点上,理性近似可能是过度工程:你有两个exp,两个sqrt.