lyn*_*nks 5 java floating-point double performance
我的情况表现非常重要.在我的算法的核心有一个方法,它使用两个double基元进行一些基本计算.每次运行该算法时,该方法被调用超过一千万次.
代码看起来像这样;
public int compare(double xA, double xB, double yA, double yB);
double x = xA * xB;
double y = yA * yB;
double diff = x - y;
return (diff < 0.0 ? -1 : (diff > 0.0 ? 1 : 0));
}
Run Code Online (Sandbox Code Playgroud)
参数xA并yA从集合中获取它们的值.这个集合可以在代码中调整.我看到很大(大约两倍)性能差异取决于我放入集合的值.似乎如果集合包含a 0.1或a 0.3,性能会受到很大影响.将设置保持为倍数0.5可以获得最佳性能.
是编译器优化x * 0.5为x >> 1等?或者这是因为0.1无法用二进制定义?
我想更好地了解这种情况,以便我可以优化它.我想这可能是一个非常难的问题,除非有人确切地知道javac和jvm(在我们的例子中是热点)如何处理双倍乘法.
只是一个夫妻几个想法:
如果值是 0.5 的倍数,则尾数中的有效位很少,因此乘法需要更少的周期似乎是可行的。实际上,乘法的有效位似乎不是问题,因为现代处理器只需要两个周期来进行双精度运算(如浮点除法与浮点乘法中所述)。
例如,我认为对于 0.5 、 1 、 2、 4 等,尾数将全为零(第一个“1”因隐含而被省略)。对于 0.75、1.5、3 等,最高有效位为“1”,后跟全零。而 0.1 将使用所有有效数精度来表示,即使这样也会有一个小误差。
关于返回结果:Math.signum()有什么问题吗?。我的意思是,也许这会起到同样的作用:
return Math.signum(x-y);
Run Code Online (Sandbox Code Playgroud)如果精度不是最重要的,您可以考虑使用单精度(浮点)。(尽管这意味着您要从 double 来回转换,那么可能不值得)。