我刚看过这个帖子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
答案 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上都经过了高度优化,甚至(特别是)。