使用int.CompareTo的性能变化
本文关键字:性能 变化 CompareTo int 使用 | 更新日期: 2023-09-27 18:01:29
[Edit 3…]
Bogus:我的原始代码使用了循环,这破坏了测试。下面的代码似乎很明显…毕竟这并不是一个"巨大"的差异。
我原以为这两种形式的CompareTo在性能上有很大的不同:
int[] arr;
int j, comp;
comp = j.CompareTo(arr[j]);
comp = arr[j].CompareTo(j);
…只是"相同"比较的相反版本!——我也尝试了同样的使用列表而不是数组。
我的原始代码通过以不同的方式在循环中加载而在测试中引入了问题。调整后的测试如下:它并没有显示出我认为我看到的"巨大"差异。
我还认为列表引入了装箱和拆箱…我将检查IL代码来了解这一点。
第一对中的两种形式与第二对中的两种形式之间仍然存在边际差异;这可能有点意思,因为代码非常相似,但产生不同的IL输出。
在Stopwatch ticks中,我的机器上得到:
int.CompareTo(List<int>[]) (Unboxing?)
337095
List<int>[].CompareTo(int) (Boxing?)
375601
int.CompareTo(Array<int>[])
157093
Array<int>[].CompareTo(int)
135420
新代码:static void Main() {
Stopwatch stopwatch = new Stopwatch();
int iterations = 100000000;
int comp = 0, accessIndex = 50, arg = 0;
List<int> list = new List<int>(100);
int[] arr = new int[100];
for (int i = 0, j = 0; j < 100; i+=2, j++) {
list.Add(i);
arr[j] = i;
}
Console.WriteLine("int.CompareTo(List<int>[]) (Unboxing?)");
stopwatch.Reset();
stopwatch.Start();
for (int i = 0; i < iterations; i++) {
comp = arg.CompareTo(list[accessIndex]);
}
stopwatch.Stop();
Console.WriteLine(stopwatch.ElapsedTicks);
Console.WriteLine();
Console.WriteLine("List<int>[].CompareTo(int) (Boxing?)");
stopwatch.Reset();
stopwatch.Start();
for (int i = 0; i < iterations; i++) {
comp = list[accessIndex].CompareTo(arg);
}
stopwatch.Stop();
Console.WriteLine(stopwatch.ElapsedTicks);
Console.WriteLine();
Console.WriteLine("int.CompareTo(Array<int>[])");
stopwatch.Reset();
stopwatch.Start();
for (int i = 0; i < iterations; i++) {
comp = arg.CompareTo(arr[accessIndex]);
}
stopwatch.Stop();
Console.WriteLine(stopwatch.ElapsedTicks);
Console.WriteLine();
Console.WriteLine("Array<int>[].CompareTo(int)");
stopwatch.Reset();
stopwatch.Start();
for (int i = 0; i < iterations; i++) {
comp = arr[accessIndex].CompareTo(arg);
}
stopwatch.Stop();
Console.WriteLine(stopwatch.ElapsedTicks);
Console.WriteLine();
}
如果您还在阅读:最后一对(与Array)的IL代码的差异仅在循环的顶部:
" int.CompareTo([]数组)"= =
// loop start (head: IL_0115)
IL_0103: ldloca.s comp
IL_0105: ldloc.s arr
IL_0107: ldloc.3
IL_0108: ldelem.i4
IL_0109: call instance int32 [mscorlib]System.Int32::CompareTo(int32)
"[]数组.CompareTo (int)"= =
// loop start (head: IL_0160)
IL_014b: ldloc.s arr
IL_014d: ldloc.3
IL_014e: ldelema [mscorlib]System.Int32
IL_0153: ldloc.2
IL_0154: call instance int32 [mscorlib]System.Int32::CompareTo(int32)
在列表版本中,我没有看到IL中有任何拳击!
骗人!
我原来的代码测试是问题…在我使用的循环中。编辑后的代码显示了相当一致的结果……