Java在for循环中使用getter还是创建局部变量?
我有一个for循环,它运行4096次,应该尽可能快。性能在这里非常重要。目前,我在循环中使用getter方法,它只返回字段中的值或对象,而这些字段在循环进行时不会更改 例如:Java在for循环中使用getter还是创建局部变量?,java,performance,loops,for-loop,getter,Java,Performance,Loops,For Loop,Getter,我有一个for循环,它运行4096次,应该尽可能快。性能在这里非常重要。目前,我在循环中使用getter方法,它只返回字段中的值或对象,而这些字段在循环进行时不会更改 例如: for (;;) { doSomething(example.getValue()); } Object object = example.getValue(); for (;;) { doSomething(object); } 使用getter是否有开销?使用以下方法是否更快 例如: for (;;
for (;;) {
doSomething(example.getValue());
}
Object object = example.getValue();
for (;;) {
doSomething(object);
}
使用getter是否有开销?使用以下方法是否更快
例如:
for (;;) {
doSomething(example.getValue());
}
Object object = example.getValue();
for (;;) {
doSomething(object);
}
如果是,访问公共字段(如example.value
)是否也是如此
编辑:我不在循环中使用
System.out.println()
编辑:某些字段不是
final
。没有字段是易变的,也没有方法(getter)是同步的如果您需要尽快运行它,您不应该在关键部分使用System.out.println
关于getter:使用getter有轻微的开销,但您不应该为此烦恼。Java确实在JIT编译器中进行了getter和setter优化。因此,最终它们将被本机代码取代。这取决于getter 如果它是一个简单的getter,那么JIT无论如何都会将它与一个直接的字段访问连接起来,因此不会有可测量的差异。从风格的角度来看,使用getter——它的代码更少 如果getter正在访问一个
volatile
字段,则会有一个额外的内存访问命中,因为该值不能保存在寄存器中,但是命中非常小
如果getter是同步的,那么使用局部变量的速度将明显加快,因为不需要每次调用都获取和释放锁,但是循环代码将使用getter调用时字段的潜在过时值。您应该更喜欢循环外的局部变量,基于以下原因:
doSomething(example.getValue())
),并允许代码为getter方法返回的值提供更好、更具体的名称,使代码更易于阅读/理解对性能的担忧很容易超出需要。我知道这种感觉。需要考虑的一些事项:
example.getValue()
或example.value
在循环中不会改变(这很难做到,除非字段是final
并且getter是微不足道的)那么从逻辑上讲,它无法避免在前一个示例中重复调用getter,因为这可能会改变程序的行为。重复的呼叫当然是一些非零量的额外工作
说到这里,在循环之外创建局部变量,不管它是否更快,因为它更清晰。也许这让你感到惊讶,但是好的代码并不总是最短的。表达意图和其他信息非常重要。在这种情况下,循环外的局部变量使任何阅读代码的人都清楚地看到,doSomething
的参数没有改变(特别是如果将其设置为final),这一点很有用。否则,他们可能需要做一些额外的挖掘,以确保他们知道程序的行为。As,在循环外部获取对象引用(object object=example.getValue();
)可能比在循环内部调用getter更快(或者至少永远不会慢),因为
- 在“最坏”的情况下,
实际上可能会在后台做一些非常昂贵的计算,尽管这被认为是“微不足道的”。通过分配一次引用并重新使用它,您只需进行一次昂贵的计算example.getValue()
- 在“最佳”情况下,
执行一些琐碎的操作,例如example.getValue()
返回值因此,在JIT编译器之后,在循环内部分配它不会比在循环外部分配更昂贵
example
发生变化,导致example.getValue()
返回对不同对象的引用,则在每次迭代中,方法doSomething(Object Object)
将通过直接调用doSomething(example.getValue())对Object
的不同实例进行实际操作代码>。另一方面,通过在循环外部调用getter并设置对返回实例的引用(objectobject=example.getValue();
),doSomething(Object)
将对对象进行n次迭代操作
语义上的这种差异可能导致多线程环境中的行为与单线程环境中的行为完全不同。此外,这不一定是一个实际的“内存中”多线程问题:如果example.getValue()
依赖于例如数据库/HDD/网络资源,则可能