“> =”测试和“==”测试一样快吗?

时间:2014-03-11 05:35:27

标签: java optimization

我正在处理hexgrid程序,需要测试角度是否为

  1. 小于30度
  2. 等于30度
  3. 介于30到60度之间
  4. 等于60度
  5. 大于60度
  6. 我有

    public int TestA(double angle)
    {
        if(angle<=30)
            {
                if(angle==30)
                    return ANGLE_EQUALS_30;
                else
                    return ANGLE_LESS_THAN_30;
            }
    
        if(angle>=60)
            {
                if(angle==60)
                    return ANGLE_EQUALS_60;
                else
                    return ANGLE_GREATER_THAN_60;
            }
        return ANGLE_BETWEEN_30_AND_60;
    }
    

    但我当然可以

    public int TestB(double angle)
    {
        if(angle<30) return ANGLE_LESS_THAN_30;
        if(angle==30) return ANGLE_EQUALS_30;
        if(angle<60) return ANGLE_BETWEEN_30_AND_60;
        if(angle==60) return ANGLE_EQUALS_60;
        return ANGLE_GREATER_THAN_60;
    }
    

    TESTA真的比TESTB快吗?或者编译器最终将&lt; = test拆分为2个测试(&lt;和==),那么TESTA实际上是在执行TESTB之后的更多测试?

    我只想写一个程序来测试它,但我觉得它会如此接近,以至于在后台运行的程序会产生更大的不同。

4 个答案:

答案 0 :(得分:4)

在宏观方案中差异是 完全可以忽略不计

Look at this demonstration.这不是一个java示例,(javascript而是),但你可以看到为什么担心这样的微优化不会真正帮助解决实际问题。

担心让您的java源易于阅读和维护。编译器应该得到比你想象的更多的功劳。

答案 1 :(得分:1)

请不要过早优化。

真正的减速是因为糟糕的算法,而不是糟糕的实现。像这样的微观推广不应该事先做好。编写可维护的代码,运行您的软件,并在遇到真正的性能问题时进行优化。 如果遇到性能问题,请执行性能分析并检查问题的确切位置。

关于“&lt; =”或“==”的实际问题。您无论如何都不会知道您的编译器/虚拟机对您的代码所做的事情。无论如何,编译器可能要好得多,更好的选择是什么,并相应地改变你的代码。

对于明确的答案,我猜“&lt; =”更快,因为对于实际上只是单个操作的处理器,并且将其拆分可能最终会有两个操作。

答案 2 :(得分:1)

首先,您是否意识到double比较是危险的?请参阅How dangerous is it to compare floating point values?What is the most effective way for float and double comparison?

如果angle参数非常随机,我会使用表查找来避免分支错误预测:

private static final byte L30 = 0, E30 = 1, L60 = 2, E60 = 3, G60 = 4;

private static final byte[] ANGLE_TABLE = new byte {
    L30, L30, L30, L30, L30, L30, L30, L30, L30, L30, L30, L30, L30, L30, L30,
    L30, L30, L30, L30, L30, L30, L30, L30, L30, L30, L30, L30, L30, L30, L30,
    E30, L60, L60, L60, L60, L60, L60, L60, L60, L60, L60, L60, L60, L60, L60,
    L60, L60, L60, L60, L60, L60, L60, L60, L60, L60, L60, L60, L60, L60, L60,
    E60, G60, G60, ... depends on the angle upper limit
};

public static int test(double angle) {
    // but not Math.round() or floor(), they are very slow
    int intAngle = (int) (angle + 0.5);
    return ANGLE_TABLE[intAngle];
}

答案 3 :(得分:0)

尝试使用“else if”,以便在满足条件时避免其他检查。

public int TestB(double angle) {
    if(angle<30) return ANGLE_LESS_THAN_30;
    else if(angle==30) return ANGLE_EQUALS_30;
    else if(angle<60) return ANGLE_BETWEEN_30_AND_60;
    else if(angle==60) return ANGLE_EQUALS_60;
    return ANGLE_GREATER_THAN_60;
}