假设我正在运行以下任意一个代码段,以获取1000个Event
条目的列表(在allEventsToAggregate
中)。如果allEventsToAggregate
中的事件按customerId
排序,每个客户大约有3个事件,我会在第一个实现中看到性能提升吗?这基本上是字符串比较与HashMap
查找性能的问题。
选项1:
Map<String, List<Event>> eventsByCust = new HashMap<String, List<Event>>();
List<Event> thisCustEntries;
String lastCust = null;
for (Event thisEvent : allEventsToAggregate) {
if (!thisEvent.getCustomerId().equals(lastCust)) {
thisCustEntries = eventsByCust.get(thisEvent.getCustomerId());
if (thisCustEntries == null) {
thisCustEntries = new ArrayList<Event>();
}
}
thisCustEntries.add(thisEvent);
eventsByCust.put(thisEvent.getCustomerId(), thisCustEntries);
lastCust = thisEvent.getCustomerId();
}
选项2:
Map<String, List<Event>> eventsByCust = new HashMap<String, List<Event>>();
for (Event thisEvent : allEventsToAggregate) {
List<Event> thisCustEntries = eventsByCust.get(thisEvent.getCustomerId());
if (thisCustEntries == null) {
thisCustEntries = new ArrayList<Event>();
}
thisCustEntries.add(thisEvent);
}
答案 0 :(得分:3)
我会看到性能提升
几乎肯定不是。除非这个块表示应用程序的关键内部循环,否则任何边际性能增益几乎肯定都不会引起注意。
因此,我会使用代码的第二个版本,因为它更清楚地表达了您的意图,因此更容易维护(以及稍微不那么容易出现细微的错误)。可维护性几乎肯定胜过使应用程序快0.001%。
答案 1 :(得分:2)
1)请记住,从HashMap成功检索项目需要进行字符串比较,以确认您确实找到了正确的项目。
2)我们似乎在谈论执行时间的微小差异,而不是真正的算法改进。这真的值得失去可读性吗?
3)对于细微的差异,真正了解的唯一方法是在实践中实际计算时间 - 实际上不仅要进行比较,还要将其组织成一个完全成熟的科学实验。关于你的编译器和运行时系统选择优化什么,cpu缓存或VM页面错误意味着什么,以及Java垃圾收集对你的算法的看法,现在还有太多担心。然后,当然,您可能会发现不同版本的Java或具有不同cpu,主板或内存大小的硬件,甚至系统运行了多长时间以及因此需要多长时间才能得到不同的答案。将其磁盘内容迁移到内存缓存中,或JIT编译Java的相关位,或其他任何内容。