Redditスレッドで問題を見つけたときに、なぜMath.sin(double)
委任するのかと思っ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);
2番目の宣言はnative
、私にとって妥当なものです。次のようにMath
述べています。
コードジェネレーターは、利用可能な場合、プラットフォーム固有のネイティブライブラリまたはマイクロプロセッサ命令を使用することをお勧めします(...)
そして問題は、StrictMath
プラットフォーム固有の実装を十分に行うネイティブライブラリではないでしょうか。インストールされているJREよりもJITがプラットフォームについて何を知ることができますか(この場合のみに集中してください)?つまり、なぜMath.sin()
ネイティブではないのですか?
ディスカッション全体を1つの投稿にまとめます。
通常、にMath
委任しStrictMath
ます。明らかに、呼び出しはインライン化できるため、これはパフォーマンスの問題ではありません。
StrictMath
native
ネイティブライブラリによってサポートされるメソッドを持つ最後のクラスです。ネイティブとは最適という意味だと思うかもしれませんが、必ずしもそうである必要はありません。StrictMath
javadocを見ると、以下を読むことができます。
(...)このパッケージの一部の数値関数の定義では、特定の公開アルゴリズムと同じ結果を生成する必要があります。これらのアルゴリズムは、よく知られたネットワークライブラリnetlibからパッケージ「Freely Distributable Math Library」fdlibmとして入手できます。Cプログラミング言語で記述されたこれらのアルゴリズムは、Java浮動小数点演算の規則に従うすべての浮動小数点演算で実行されると理解されます。
このドキュメントを理解する方法は、ネイティブライブラリの実装がマルチプラットフォームであり、予測可能な結果を生成することが知られているfdlibmライブラリのStrictMath
観点から実装されていることです。マルチプラットフォームであるため、すべてのプラットフォームで最適な実装になるとは期待できません。これは、スマート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で定義されて__kernel_sin
おり、ヘッダーfdlibm.hから直接来る関数をいくつかの場所で参照しています。
私は一時的に自分の回答を受け入れていますが、回答が出たら、より有能な回答を受け入れていただければ幸いです。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加