java – 通过位操作更快地实现Math.abs()
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了java – 通过位操作更快地实现Math.abs(),小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含1893字,纯文字阅读大概需要3分钟。
内容图文
![java – 通过位操作更快地实现Math.abs()](/upload/InfoBanner/zyjiaocheng/732/fadd04da463b49bfa84244843c4472c3.jpg)
Math.abs(x)的正常实现(由Oracle实现)由下式给出
public static double abs(double a) {
return (a <= 0.0D) ? 0.0D - a : a;
}
将数字符号的一位编码设置为零(或一个)不是更快吗?
我想只有一位编码数字的符号,并且它总是相同的位,但我可能错了.
或者我们的计算机通常不适合使用异常指令对单个位进行操作?
如果可以更快地实施,你能给它吗?
编辑:
我已经向我指出Java代码是独立于平台的,因此它不能依赖于单个机器的异常指令.但是,为了优化代码,JVM热点优化器确实考虑了机器的细节,并且可能会应用正在考虑的非常优化.
然而,通过一个简单的测试,我发现至少在我的机器上,Math.abs函数似乎没有针对单个atomary指令进行优化.我的代码如下:
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
假设乘法由一个atomary指令执行,似乎至少在我的机器上,JVM热点优化器不会将Math.abs函数优化为单个指令操作.
解决方法:
我的第一个想法是,这是因为NaN(非数字)值,即如果输入是NaN,它应该返回而不做任何改变.但这似乎并不是必需的,因为Harold的测试表明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()全部内容,希望文章能够帮你解决java – 通过位操作更快地实现Math.abs()所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。