gpt4 book ai didi

java - 通过位操作更快地实现 Math.abs()

转载 作者:塔克拉玛干 更新时间:2023-11-01 22:47:53 25 4
gpt4 key购买 nike

Math.abs(x) 的正常实现(由 Oracle 实现)由

给出
public static double abs(double a) {
return (a <= 0.0D) ? 0.0D - a : a;
}

将数字符号的一位编码设置为零(或一)不是更快吗?我假设只有一位对数字的符号进行编码,并且它总是相同的位,但我可能错了。

还是我们的计算机通常不适合使用原子指令对单个位进行运算?

如果可以更快地实现,您能提供吗?

编辑:

有人向我指出,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 函数优化为单指令操作。

最佳答案

我的第一个想法是,这是因为 NaN (非数字)值,即如果输入是 NaN它应该原样返回。但这似乎不是必需的,因为哈罗德的测试表明 JVM 的内部优化不会保留 NaN 的符号(除非您使用 StrictMath )。

documentation Math.abs 的作者说:

In other words, the result is the same as the value of the expression: Double.longBitsToDouble((Double.doubleToLongBits(a)<<1)>>>1)

因此,此类的开发人员知道位操作选项,但他们决定反对。

很有可能,因为优化此 Java 代码毫无意义。在大多数环境中,热点优化器一旦在热点中遇到它,就会用适当的 FPU 指令替换它的调用。很多 java.lang.Math 都会发生这种情况方法以及Integer.rotateLeft和类似的方法。他们可能有纯 Java 实现,但如果 CPU 有指令,它就会被 JVM 使用。

关于java - 通过位操作更快地实现 Math.abs(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19655832/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com