我想知道,当我在Reddit thread中发现问题时,为什么Math.sin(double)委托(delegate)给StrictMath.sin(double)。提到的代码片段如下所示(JDK 7u25):

Math.java:

public static double sin(double a) {
    return StrictMath.sin(a); // default impl. delegates to StrictMath
}

StrictMath.java:
public static native double sin(double a);

第二个声明是native,对我来说是合理的。 Math的文档指出:



,问题是:实现平台特定于StrictMath的本机库不够吗?除了已安装的JRE,JIT还可以了解有关平台的更多信息(请仅关注这种情况)?换句话说,为什么Math.sin()还不是原生的?

最佳答案

我将尝试在单个帖子中总结整个讨论。

通常,Math委托(delegate)给StrictMath。显然,该调用可以是inlined,因此这不是性能问题。
StrictMath是最终类,其原生库支持native方法。有人可能会认为,本机意味着最优,但这不一定是事实。通过StrictMath javadoc可以看到以下内容:



我对这个文档的理解是,实现StrictMath的本机库是根据fdlibm库实现的,fdlibm库是多平台的,已知会产生可预测的结果。由于它是多平台的,因此不能期望它是每个平台上的最佳实现。我相信这是智能JIT可以微调实际性能的地方,例如通过对输入范围的统计分析并相应地调整算法/实现。

深入研究实现,很快发现,备份StrictMath的本机库实际上是使用 fdlibm:

OpenJDK 7中的StrictMath.c源代码如下所示:

   #include "fdlibm.h"
   ...
   JNIEXPORT jdouble JNICALL
   Java_java_lang_StrictMath_sin(JNIEnv *env, jclass unused, jdouble d)
   {
       return (jdouble) jsin((double)d);
   }

正弦函数在fdlibm/src/s_sin.c中定义,在某些地方引用直接来自头文件fdlibm.h的__kernel_sin函数。


当我暂时接受自己的答案时,我很高兴在出现时接受一个更称职的答案。

07-24 18:58