Java中的int vs float算术效率

时间:2010-07-28 07:39:15

标签: java performance math primitive

我正在编写一个使用Dijkstra算法查找图中最小路径的应用程序。图中节点和边的权重是float个数,因此算法在浮点数上做了很多算术。如果我将所有重量都转换为int s,我可以改善运行时间吗?在Java中,int算术运算是否比浮动运算更快?

我试着写一个简单的基准来检查出来,但我对我得到的结果不满意。可能编译器优化了程序的某些部分,因此结果对我来说看起来不太好。


编辑:

我正在尝试解决的问题是在信息检索字段中。应用程序应显示作为一组关键字提出的查询的答案。

我的数据结构是加权有向图。给定一组叶节点,我必须找到连接这些节点并向用户显示答案的最小树。权重由部分基于tf / idf技术的加权函数指定。用户不知道我分配给节点和边缘的权重,他只想看到与他提出的查询相关的答案。因此不需要精确的结果,只需根据他们的权重枚举答案。只是本地使用加权函数(正如我提到它基于tf / idf)给出浮点权重,所以我到目前为止使用了浮点数。

我希望这会为这个问题增加一些背景知识。

7 个答案:

答案 0 :(得分:2)

对于简单操作int更快,但是对于int,您可能需要做更多工作才能获得相同的结果。 e.g。

as float

float f = 15 * 0.987;

as int

int i = 15 * 987 / 1000;

额外除法意味着int操作可能需要更长时间。

答案 1 :(得分:1)

与此类事情一样,您应该为自己设定一些性能目标,然后对应用进行概要分析以确定它是否符合这些目标。

很多时候你会发现令人惊讶的结果;所用的时间几乎不受基础数字类型的影响,或者你的算法不是最理想的。

关于编译器优化 - 它们是性能优化的真实且有效的部分。

如果使用类型A理论上比使用类型B更快,但是你的编译器可以在真实场景中更快地优化类型B,那么这是一个有价值的证据,而不是消失的来源。

答案 2 :(得分:1)

在我的机器上,整数减法比双减法快2.5倍。 然而,整数乘法仅比双乘法快约1.5倍。

以下测试适用于随机数据,这可能会阻止编译器进行优化。

// test whether int subs are faster than double subs
public void compareIntAndFloatSubtraction(){

    int N = 100000;  // input array size
    int k = 100000;  // number of mathematical operations performed on each element

    // generate random data
    int[] ints = new int[N];
    double[] doubles = new double[N];
    Random r = new Random(1l);
    for (int i = 0; i < N; i++) {
        ints[i] = r.nextInt();
        doubles[i] = r.nextDouble();
    }

    // measure integer subtractions
    long before = System.currentTimeMillis();
    for (int i = 1; i < N; i++) {
        for (int j = 0; j < k; j++) {
            ints[i] -= ints[i-1];  // referring to another element might prevent from optimization also
        }
    }
    System.out.println(String.format("time needed for int subs [ms]: %s", System.currentTimeMillis()-before));

    // measure double subtractions
    before = System.currentTimeMillis();
    for (int i = 1; i < N; i++) {
        for (int j = 0; j < k; j++) {
            doubles[i] -= doubles[i-1];
        }
    }
    System.out.println(String.format("time needed for double subs [ms]: %s", System.currentTimeMillis()-before));

}

答案 3 :(得分:0)

如果你只想比较权重,你应该更喜欢int浮动。

答案 4 :(得分:0)

一般情况下,出于性能原因,您不必担心intfloat之间的选择。

以下是Java Puzzlers附录中的摘录:

  

浮点运算是不精确的。不要在需要精确结果的地方使用浮点数;相反,使用整数类型或BigDecimal。首选doublefloat

除非你有充分的理由,否则如果必须使用浮点运算,通常应该更喜欢doublefloat。如果需要确切结果,请继续使用BigDecimal;它会变慢,因为它不是原始的,但除非分析显示它是不可接受的,这通常是最好的选择。

如果必须使用浮点运算,那么尝试使用int来优化它是不明智的。这可能是一个过早的优化,只会使代码变得复杂化。以最自然,最可读的方式书写。不要为了轻微的性能提升而不必要地使代码复杂化。

如果您实际上不需要浮点运算,那么请务必使用intlong

答案 5 :(得分:0)

我认为性能在很大程度上取决于算法和运行软件的平台。

如果您正在X86平台上进行矩阵/数组计算,运行时可能会对其进行优化以使用SSE,这是一个浮点/双精度扩展指令集。

在其他平台上,运行时可能会优化到OpenCL(我不相信任何人现在都这样做,但可能会发生:)。我不知道在这样的平台上运行得最快,在什么条件下。可能只是OpenCL针对整数工作负载进行了优化。

在这些情况下,我会得出结论,此时优化数据类型(float或int)并没有用,只是优化代码的可读性。

如果您的代码具有高性能关键性,而且您确切知道系统现在和将来运行的硬件,您可以使用各种算法测试典型工作负载,并选择最符合您需求的工作负载。

但一般来说,只需使用您可以理解的算法,保持代码可读,从而将错误数量降低。如果结果不正确,快速代码的价值不高:)

答案 6 :(得分:-6)

我不这么认为。

Float是4个字节。而java中的Int也是4个字节。

为什么不使用Date(java.util.Date)来获取运行时间?

您可以定义一个拥有100000个节点的图表。然后计算它。

相关问题