我正在处理hexgrid程序,需要测试角度是否为
我有
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之后的更多测试?
我只想写一个程序来测试它,但我觉得它会如此接近,以至于在后台运行的程序会产生更大的不同。
答案 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;
}