我有以下插入排序算法实现:
private static void InsertionSort(List<int> array)
{
for (int i = 1; i < array.Count; ++i)
{
for (int j = i; j > 0 && array[j - 1] > array[j]; --j)
{
//swap(array, j, j-1);
int temp = array[j];
array[j] = array[j-1];
array[j-1] = temp;
}
}
}
private static void swap(List<int> array, int i, int j)
{
int temp = array[i];
array[i] = array[j];
array[j] = temp;
}
当我使用swap(array, j, j-1);
运行我的算法时,它需要花费更多的时间(50000个元素+2秒),而不是我的函数体内联。
为什么?
答案 0 :(得分:15)
手动内联方法没有错,只是没有必要。内联小方法是抖动执行的standard optimizations之一。这并不总是发生,但在.NET 4.6.1中,x86和x64抖动在此示例代码中执行内联交换()。而且,他们还展开内部循环以产生每次传递两个交换,这种手动优化程序员通常会跳过。
正确地对.NET应用程序进行基准测试并不总是那么直截了当。 非常运行程序的Release版本非常重要。并且不使用调试器。虽然后者易于修复,但请使用工具&gt;选项&gt;调试&gt;一般&gt;取消勾选“抑制JIT优化”选项。没有充分理由重新开启。
您现在还可以看到生成的机器代码,在InsertionSort()上设置断点以及何时命中使用Debug&gt; Windows&gt;拆卸。倾向于让人们的眼睛流血,但很容易看到你得到两个内联交换()。我会把你的汇编转储给你,只是看看吧。你应该清楚地看到测量的差异。这是我得到的:
在x64上使用带有50,000个随机整数的List上的swap()运行它5次:
00:00:05.4447216
00:00:05.2928558
00:00:05.6960587
00:00:05.2835343
00:00:05.2809591
相同的测试,但现在用手内联swap():
00:00:05.3015856
00:00:05.2877402
00:00:05.6369775
00:00:05.2603384
00:00:05.2616389
需要尽可能长的时间。
如果没有显示我使用List.Sort()得到的结果,我会失职:
00:00:00.0075878
00:00:00.0073398
00:00:00.0076528
00:00:00.0078046
00:00:00.0066319