我有以下插入排序算法实现:
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;
}
Run Code Online (Sandbox Code Playgroud)
当我运行我的算法时,swap(array, j, j-1);它需要花费更多的时间(50000个元素+2秒),而不是我的函数体内联.
为什么?
Han*_*ant 15
手动内联方法没有错,只是没有必要.内联小方法是抖动执行的标准优化之一.这并不总是会发生,但在.NET 4.6.1中,x86和x64抖动都在此示例代码中执行内联swap().而且,他们还展开内部循环以产生每次传递两次交换,这种手动优化程序员通常会跳过.
正确地对.NET应用程序进行基准测试并不总是那么直截了当. 运行程序的Release版本非常重要.并且不使用调试器.虽然后者很容易修复,但请使用工具>选项>调试>常规>取消选中"抑制JIT优化"选项.没有充分的理由将其重新打开.
您现在还可以看到生成的机器代码,在InsertionSort()上设置断点以及何时命中使用Debug> Windows> Disassembly.倾向于让人们的眼睛流血,但很容易看到你得到两个内联交换().我会把你的汇编转储给你,只是看看吧.你应该清楚地看到测量的差异.这是我得到的:
使用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
Run Code Online (Sandbox Code Playgroud)
相同的测试,但现在手工内联swap():
00:00:05.3015856
00:00:05.2877402
00:00:05.6369775
00:00:05.2603384
00:00:05.2616389
Run Code Online (Sandbox Code Playgroud)
需要尽可能长的时间.
我将无法显示List.Sort()得到的结果:
00:00:00.0075878
00:00:00.0073398
00:00:00.0076528
00:00:00.0078046
00:00:00.0066319
Run Code Online (Sandbox Code Playgroud)