【问题标题】:Floating point operations is slower when small values are used?使用小值时浮点运算速度较慢?
【发布时间】:2009-07-14 15:07:59
【问题描述】:

我有以下简单的程序,可以多次将两个不同的浮点数相乘。如您所见,其中一个数字非常小。当我计算执行两个乘法的时间时,我很惊讶这个小数字比另一个花的时间长得多。使用小型双打似乎更慢...有谁知道发生了什么?

public static void main(String[] args) throws Exception
{
    long iterations = 10000000;
    double result;
    double number = 0.1D;
    double numberA = Double.MIN_VALUE;
    double numberB = 0.0008D;

    long startTime, endTime,elapsedTime;


    //Multiply numberA
    startTime = System.currentTimeMillis();

    for(int i=0; i < iterations; i++)
        result = number * numberA;

    endTime = System.currentTimeMillis();
    elapsedTime = endTime - startTime;

    System.out.println("Number A) Time elapsed: " + elapsedTime + " ms");

    //Multiply numberB
    startTime = System.currentTimeMillis();
    for(int i=0; i < iterations; i++)
        result = number * numberB;

    endTime = System.currentTimeMillis();
    elapsedTime = endTime - startTime;

    System.out.println("Number B) Time elapsed: " + elapsedTime + " ms");
}

结果:

数字 A) 已用时间:3546 毫秒
数字 B)经过的时间:110 毫秒

平台 Windows,Java 1.6.0_07

谢谢, 迭戈

【问题讨论】:

    标签: java floating-point


    【解决方案1】:

    在 IEEE 758 浮点值的最小表示附近运行时,您可能会得到“denormal”的结果。这些有时(尽管并非总是)处理得更慢。我怀疑 JVM 以某种方式专门处理它们,而不是依赖纯硬件支持,从而导致性能下降。

    【讨论】:

      【解决方案2】:

      我的猜测是编译器被替换了

      number * numberB;
      

      具有其确切值,因为numbernumberB 都是编译器知道此时尚未更改的常量值。但是,numberA 不是一个常量值(它的值是特定于平台的),因此您必须每次都实际进行计算。尝试将Double.MIN_VALUE 替换为其实际值,看看它们的性能是否相似。

      【讨论】:

      • 不,我用 4.9E-324 替换了它,它得到了相同的结果......谢谢!!
      • 使用 0.0000008 并开始增加 8 之前的零。
      • 嗯,我也完全错过了您将 epsilon 乘以小于 1 的数字的事实。这几乎肯定与它有关!
      • 我的意思是根据对数缩放的测试值绘制直方图。
      • 我在 Ubuntu 8.04 中运行它并得到:数字 A) 时间流逝:44 毫秒数字 B) 时间流逝:49 毫秒 Windows JVM 有点奇怪...
      【解决方案3】:

      可能是您输入了“非正规”数字的范围(请参阅 IEEE754 格式)。在浮点单元中处理这些数字可能需要更多时间。

      【讨论】:

      • 我在 Ubuntu 8.04 中运行它并得到:数字 A) 时间流逝:44 毫秒数字 B) 时间流逝:49 毫秒 Windows JVM 有点奇怪...
      【解决方案4】:

      这似乎是 Windows JVM 中的错误

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-09-24
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多