有关性能的一些思考
性能是一个重要且很复杂的话题。简单来说,性能调优就是要加快系统的执行,因此就是要尽可能使用执行速度更快的组件。那到底哪个组件更快,哪个方法更快?看似简单的问题却是没有答案的。在大部分场景中,并没有绝对的快和慢。性能需要从不同角度、不同场景进行评估和取舍。 下面是我用JMH对HashMap、ConcurrentHashMap、Collections.synchronizedMap(new HashMap())、CopyOnWriteArrayList以及ConcurrentLinkedQueue的性能测试
JMH测试机器环境
JDK1.8 MAC OS 6核 i7处理器
HashMap、ConcurrentHashMap、Collections.synchronizedMap(new HashMap())
在单线程下,Collections.synchronizedMap(new HashMap())不论在get上还是size上,吞吐量均最低;在get方面,concurrentHashMap比HashMap略高一点;在size方法上,concurrentHashMap要比HashMap的慢很多。 在开启两个线程的情况下,正常来说,吞吐量可以增加一倍。尤其完全不关心线程安全的HashMap,增加线程数量可以几乎等比增加其吞吐量。值得注意的是,ConcurrentHashMap的size方法的吞吐量也等比增加一倍。但是通过同步包装的HashMap由于线程间的竞争导致性能急剧下降。对于get()方法,ConcurrentHashMap的合理优化,避免了线程的竞争,因此其性能和HashMap几乎等同,甚至还略胜一点。
CopyOnWriteArrayList、ConcurrentLinkedQueue
在并发环境下,写性能要远远低于读性能。就读的性能而言,进行只读不写的Get操作,两者性能都不错。但是由于实现上的差异,ConcurrentLinkedQueue类的size操作明显要小于CopyOnWriteArrayList类的。就写的性能而言,观察结果包含1000个元素的List与包含少量元素的List之间性能相差不大。 在元素总量不大的情况下,在绝大部分场景中,CopyOnWriteArrayList类要优于ConcurrentLinkedQueue类
|