我制作了一个串行MergeSort和一个并行MergeSort。两者都将输入列表分为左半部分和右半部分,并在其上调用sort
。源代码几乎完全相同。它们之间的区别在于,并行MergeSort具有if语句,该语句检查是否需要创建线程或仅像串行版本一样调用sort
。代码段:
if (threadDepth < maxThreadDepth) {
// make threads that call sort
} else {
sort(left, threadDepth + 1, maxThreadDepth);
sort(right, threadDepth + 1, maxThreadDepth);
}
当我使用maxThreadDepth = 0
时,if语句始终为false,并且并行操作与串行版本相同。
我计算两种算法花费的时间,然后看到一些非常奇怪的东西。当maxThreadDepth = 0
时,并行版本比串行版本快!我希望它会慢一些,因为它还有一个额外的if语句要处理。即使JVM优化了这个if语句(它知道它总是错误的),它也永远不会更快!
我对这两种算法都运行了1000次,并跟踪它们花费的时间:
List<Long> times = new ArrayList<>();
for(int i = 0, i < 1000, i++){
long start = System.nanoTime();
serial.MergeSort.sort(...); // or parallel.MergeSort.sort(...)
long end = System.nanoTime();
times.add(end - start);
}
我丢弃了前900次,并计算了两种算法运行所需的平均时间。有人知道为什么无线程并行版本比串行版本快吗?作为输入,我使用了各种大小(1000、10000、100000)的整数列表,所有这些都有令人惊讶的行为。