【发布时间】:2016-11-16 15:40:26
【问题描述】:
我目前正在处理大量嵌套的关卡对象,并且正在考虑性能。
假设我有以下课程:
class Address {
private String doorNumber;
private String street;
...
}
还有另一个类 Customer。
class Customer {
private List<Address> addressList;
private String firstName;
.....
.....
.....
}
当我尝试像下面这样访问它时:
public static void main(String[] str) {
Customer customer = new Customer();
// ... and add addresses to this Customer object.
// Set 1
// And if I then do...
customer.getAddressList().get(0).getHouseNumber();
customer.getAddressList().get(0).getStreet();
// OR
// Set 2
Address address = customer.getAddressList().get(0);
address.getHouseNumber();
address.getStreet()
}
我知道访问地址的第一组行不是干净的代码,我认为编译器会对此进行排序,但事实并非如此。因为当我反编译我的代码时,我得到了完全相同的东西,所以不确定编译器是否在那里进行了任何优化。所以我的第一个问题是为什么编译器不清理它并将其分配给临时变量?
我的下一个问题是,这与性能有关吗?除了第一个不是很干净的代码之外,哪个是两者中性能更好的代码。这是否意味着,我的第二组代码在编译期间会在内部被翻译成第一行?
最后一个问题,在一个类上调用变量是否比它的 getter 方法更优化?我只是在考虑性能,没有干净的编码。
【问题讨论】:
-
第二个版本的性能会更好,特别是如果
addressList是LinkedList<>或其他List<>,而get不是O(1)。 (假设您将比第一个元素更深入地挖掘。) -
谢谢@bradimus。这个想法是我是否必须对变量分配保持勤奋,或者 Java 编译器是否进行了任何优化?不确定。
-
您可以通过基准测试自己检查性能。在循环中运行代码数千次并使用
System.nanoTime()测量时间。 -
如果您要进行基准测试,请确保正确执行:stackoverflow.com/questions/504103/…
-
谢谢@AndréStannek。性能可能因 JVM 的不同实现而异。而且我可能无法访问不同类型的 JVM 实现。我只是想看看是否有人对此或编译器的内部工作有所了解。真的只是发人深省吗?这有意义吗?