包含许多“if”的临界循环,其输出是常量:如何保存条件测试?对于Java;)

时间:2011-04-05 14:31:23

标签: java optimization javac

我刚看过这个帖子Critical loop containing many "if" whose output is constant : How to save on condition tests?

和这一个Constant embedded for loop condition optimization in C++ with gcc正是我想用Java做的。

我有一些if条件被多次调用,条件由初始化时定义的属性组成,并且不会改变。

Javac是否会通过删除未使用的条件分支来优化字节码,从而避免花时间测试它们? 我必须将属性定义为final还是无用?

谢谢你的帮助,

的Aurelien

4 个答案:

答案 0 :(得分:2)

Java编译时优化非常缺乏。如果你可以使用switch语句,它可能会做一些简单的优化。如果属性的数量非常大,那么HashMap将是您最好的选择。

我最后会说,这种事情很少成为瓶颈,试图过早地优化它会适得其反。实际上,如果您的代码被调用很多,那么JIT优化器将尽最大努力使您的代码运行得更快。只要说出你想要发生什么,只关心当你发现实际上值得花时间来优化它时的“如何”。

答案 1 :(得分:0)

在OO语言中,解决方案是使用委托或命令模式而不是if / else forest。

因此,您的属性需要实现像IAttribute这样的公共接口,该接口具有方法run()(或使所有属性实现Runnable)。

现在你可以简单地调用方法而不需要在循环中做出任何决定:

for(....) {
    attr.run();
}

如果无法向属性添加方法,则会更复杂一些。在这种情况下,我的解决方案是使用enum和包含runnables的EnumMap。访问EnumMap几乎就像数组访问(即O(1))。

for(....) {
    map.get(attr).run();
}

答案 2 :(得分:0)

我不知道有关此问题的Java细节,但您可能希望研究一种名为Memoization的技术,它允许您在表中查找函数的结果而不是调用函数。实际上,memoization使您的程序“记住”给定输入的函数结果。

答案 3 :(得分:0)

尝试用运行时多态性替换if。不,这并不像你想象的那么奇怪。

例如,如果你有这个:

for (int i=0; i < BIG_NUMBER; i++) {
  if (calculateSomeCondition()) {
    frobnicate(someValue);
  } else {
    defrobnicate(someValue);
  }
}

然后将其替换为Function,取自Guava,但可以替换为任何其他适合的界面):

Function<X> f;
if (calculateSomeCondition()) {
  f = new Frobnicator();
else {
  f = new Defrobnicator();
}

for int (i=0; i < BIG_NUMBER; i++) {
  f.apply(someValue);
}

如果只有少数可能的调用目标,方法调用在大多数现代JVM上都经过了高度优化,甚至(特别是)。