为什么LinkedList比常规数组(没有新的分配)比big n慢10倍:
Deque<Boolean> tail = new LinkedList<>();
for (int i = 1; i <= n; i++) {
tail.addFirst(true);
tail.pollLast();
}
我的第一个好处是gc时间,但只需3.5秒即可完成。 什么是找到背后原因的最佳方法?
答案 0 :(得分:1)
找到背后原因的最佳方法是什么?
有很多方法:
将您的示例转换为适当的基准并使用分析器运行它。然后查看花费的时间。
查看您正在调用的LinkedList方法的源代码。
检查Javac编译器为您的代码和LinkedList代码生成的字节代码。
检查JIT编译器为您的代码和LinkedList代码生成的本机代码。
(我会让你自己调查一下,因为我怀疑它会显示出任何特别意外的事情。)
我的第一个猜测是gc时间,但仅在3.5秒内需要100毫秒。
很可能大部分时间都是分配和初始化链表节点对象,以及列表方法的其他开销。
如果GC确实需要在构建列表时运行,那么LinkedList
情况下的GC开销会比数组情况稍大一些。但我怀疑实际发生的事情是GC实际上正在回收在代码加载和(可能)JIT编译期间创建的对象。在两种情况下,列表/数组构建期间产生的实际可收集垃圾量应为零。
您的基准测试方法也可能会扭曲结果。例如,我注意到您的pollLast
调用没有做任何有用的事情......关于构建列表。另一个问题可能是您不允许JVM预热效果。
通常,您看到的10倍差异对应于Java列表与阵列性能的“接受的智慧”。如果您使用的是ArrayList
而不是LinkedList
,那么性能将更接近于裸阵列,尤其是如果您对ArrayList
容量进行了很好的估算。