JVM是否通过在同一方法中存储类似方法调用的结果来修复我的低效代码?

时间:2015-06-28 14:06:48

标签: java jvm

给出代码

if (linkedHashMap.get(string) == null) { 
  linkedHashMap.put(string, object);
} else { 
  linkedHashMap.get(string).increment();
}

Interputer / JVM是否决定:linkedHashMap.get(string)使用两次,因此为此调用分配一个变量或者它是否只是两次效率相同的调用?

2 个答案:

答案 0 :(得分:2)

鉴于一个足够先进的JIT和get()的足够琐碎的实现 - 以及它所调用的equals(),它可能会在某个时候被优化掉。但是没有保证。

get()的实现细节非常重要,因为它可能包含内存可见性效果(原子,锁),或者具有超出编译器执行冗余代码消除的能力的复杂性。

E.g。我猜想Collections.singletonMap生成的地图很容易优化。但是ConcurrentHashMap肯定不是因为它使用了挥发物和锁。

但最终获得确定性的唯一方法是查看所讨论方法的生成程序集,在它变得足够热以使其被调用的内容被JIT之后。

答案 1 :(得分:0)

没有Interputer这样的东西。即时编译器可能会识别重复,但前提是被调用的方法足够简单以便内联,这可能不是HashMap.get的情况。也就是说,冗余查找只需不到一微秒,因此除非代码每秒执行数百万次,否则对性能的影响不会很大。

避免冗余查找的简单方法(也适用于ConcurrentMaps)将是

linkedHashMap.merge(string, 1, Integer::sum);