.NET 4.0 中的 Array.Sort() 发生了什么? TrySZSort() 消失了吗?
我想知道为什么下面的代码片段没有给出预期的结果?它对一个不太小的随机数组进行排序,并使用 3 种不同的方法。我期望的速度是这样的:
- Array.Sort() - 最快通过使用本机 TrySZSort 函数,正如我从 .NET 2.0 中回忆的那样
- 通过使用自定义比较器类进行降序排序
- lambda 表达式排序。
代码:
class DescComparer : IComparer<double> {
// simple comparison
// (yes, its not exactly correct ...)
public int Compare(double x, double y) {
return (x > y) ? -1 : 1;
}
}
static void Main(string[] args) {
Stopwatch sw = new Stopwatch();
Random rand = new Random();
DescComparer comparer = new DescComparer();
double[] a = new double[1000000];
for (int r = 0; r < 20; r++) {
// init array
for (int i = 0; i < a.Length; i++) a[i] = rand.NextDouble();
sw.Restart();
Array.Sort(a);
sw.Stop();
Console.WriteLine("ascending took: {0} ms ", sw.ElapsedMilliseconds);
// init array
for (int i = 0; i < a.Length; i++) a[i] = rand.NextDouble();
sw.Restart();
Array.Sort<double>(a, comparer);
sw.Stop();
Console.WriteLine("descending took: {0} ms ", sw.ElapsedMilliseconds);
// init array
for (int i = 0; i < a.Length; i++) a[i] = rand.NextDouble();
sw.Restart();
Array.Sort<double>(a, (x,y) => -x.CompareTo(y));
sw.Stop();
Console.WriteLine("desc lambda took: {0} ms ", sw.ElapsedMilliseconds);
}
Console.Read();
}
但奇怪的是,它给出了以下内容:
ascending took: 514 ms
descending took: 537 ms
desc lambda took: 915 ms
ascending took: 511 ms
descending took: 492 ms
desc lambda took: 923 ms
ascending took: 511 ms
descending took: 483 ms
desc lambda took: 912 ms
ascending took: 511 ms
descending took: 485 ms
desc lambda took: 914 ms
ascending took: 518 ms
descending took: 485 ms
desc lambda took: 924 ms
... a.s.o. ...
所以,lambda 确实是最慢的。但为什么普通的升序 Array.Sort 不再更快了呢?是因为 Array.Sort(T[], Comparer) 已得到改进,还是 TrySZSort 只是被删除了?或者我错过了什么?
(发布版本,没有调试,现在没有可用的反射器;))谢谢!
更新: 根据@Reed Copsey 的提示,lambda 表达式是不公平的。我尝试将其更改为与比较器相同的值。速度加快了。 Asc/lambda 从 55% -> 55% 75%。所以它仍然慢得多。
I wonder why the following snippet does not give the expected result? It sorts a not too small random array and uses 3 different methods for it. I was expecting the speed to come out as so:
- Array.Sort() - fastest by using the native TrySZSort function as I recall from .NET 2.0
- Descending sort by using the custom Comparer class
- The lambda expression sort.
The Code:
class DescComparer : IComparer<double> {
// simple comparison
// (yes, its not exactly correct ...)
public int Compare(double x, double y) {
return (x > y) ? -1 : 1;
}
}
static void Main(string[] args) {
Stopwatch sw = new Stopwatch();
Random rand = new Random();
DescComparer comparer = new DescComparer();
double[] a = new double[1000000];
for (int r = 0; r < 20; r++) {
// init array
for (int i = 0; i < a.Length; i++) a[i] = rand.NextDouble();
sw.Restart();
Array.Sort(a);
sw.Stop();
Console.WriteLine("ascending took: {0} ms ", sw.ElapsedMilliseconds);
// init array
for (int i = 0; i < a.Length; i++) a[i] = rand.NextDouble();
sw.Restart();
Array.Sort<double>(a, comparer);
sw.Stop();
Console.WriteLine("descending took: {0} ms ", sw.ElapsedMilliseconds);
// init array
for (int i = 0; i < a.Length; i++) a[i] = rand.NextDouble();
sw.Restart();
Array.Sort<double>(a, (x,y) => -x.CompareTo(y));
sw.Stop();
Console.WriteLine("desc lambda took: {0} ms ", sw.ElapsedMilliseconds);
}
Console.Read();
}
But strangely, it gives the following:
ascending took: 514 ms
descending took: 537 ms
desc lambda took: 915 ms
ascending took: 511 ms
descending took: 492 ms
desc lambda took: 923 ms
ascending took: 511 ms
descending took: 483 ms
desc lambda took: 912 ms
ascending took: 511 ms
descending took: 485 ms
desc lambda took: 914 ms
ascending took: 518 ms
descending took: 485 ms
desc lambda took: 924 ms
... a.s.o. ...
So, the lambda really is slowest. But how comes, the plain ascending Array.Sort is not faster anymore? Is it, because Array.Sort(T[], Comparer) has been improved or has TrySZSort simply been removed? Or did I miss something?
(Release build, no Debug, no Reflector available right now ;) ) Thanks!
UPDATE:
According to the hint by @Reed Copsey, the lambda expression is not fair. I tried to change it to the same as the comparer does. The speed went up. Asc / lambda went from 55% -> 75%. So it still is considerably slower.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
嗯,这里有两个问题。首先,这实际上取决于您的构建和系统 -
在我的系统上,在 x64 中,
Array.Sort()
是最快的,速度相当快:在 x86 上,事情略有不同 - 但与您所显示的意义几乎不一样:
当您运行这些计时时,您是否附加了视觉工作室主机?如果您在 VS 中运行(即:默认情况下使用 F5 而不是 Ctrl+F5),即使是发布版本也会显着变慢。
另请注意,就 lambda 而言,您的测试并不完全公平。您应该使用相同的测试机制,即:
Well, there's two issues here. First, this really depends on your build and system -
On my system, in x64,
Array.Sort()
is the fastest, by a significant amount:On x86, things are slightly different - but not nearly the same significance as you're showing:
Did you have the visual studio host attached when you ran these timings? Even a release build will be dramatically slower if you run within VS (ie: F5 instead of Ctrl+F5 by default).
Also note that your test isn't completely fair, in regards to the lambda. You should use the same mechanism for testing, which would be: