の通常の実装Math.abs(x)
(Oracle によって実装されている) は、次の式で与えられます。
public static double abs(double a) {
return (a <= 0.0D) ? 0.0D - a : a;
}
数値の符号の 1 ビット コーディングを 0 (または 1) に設定する方が高速ではありませんか? 数値の符号をコーディングするビットは 1 つだけで、常に同じビットであると思いますが、これは間違っている可能性があります。
それとも、私たちのコンピューターは一般的に、原子命令で単一ビットの操作を行うのに適していませんか?
より高速な実装が可能であれば、それを提供できますか?
編集:
Java コードはプラットフォームに依存しないため、単一のマシンの不可分命令に依存することはできないと指摘されました。ただし、コードを最適化するために、JVM ホットスポット オプティマイザはマシンの詳細を考慮し、検討中の最適化そのものを適用する可能性があります。
ただし、簡単なテストを通じて、少なくとも私のマシンでは、Math.abs
関数が単一の原子命令に最適化されていないように見えることがわかりました。私のコードは次のとおりです。
long before = System.currentTimeMillis();
int o = 0;
for (double i = 0; i<1000000000; i++)
if ((i-500)*(i-500)>((i-100)*2)*((i-100)*2)) // 4680 ms
o++;
System.out.println(o);
System.out.println("using multiplication: "+(System.currentTimeMillis()-before));
before = System.currentTimeMillis();
o = 0;
for (double i = 0; i<1000000000; i++)
if (Math.abs(i-500)>(Math.abs(i-100)*2)) // 4778 ms
o++;
System.out.println(o);
System.out.println("using Math.abs: "+(System.currentTimeMillis()-before));
次の出力が得られます。
234
using multiplication: 4985
234
using Math.abs: 5587
乗算が不可分命令によって実行されると仮定すると、少なくとも私のマシンでは、JVM ホットスポット オプティマイザーはMath.abs
関数を単一の命令操作に最適化していないようです。