【发布时间】:2021-02-16 07:34:35
【问题描述】:
其中一个 .Net Core 版本(我不确定是哪个)引入了优化,如果您编写这样的代码:
int smallest = new[]{ 7, 2, 4, 6, 0, 1, 6, 9, 8 }.OrderBy(i => i).First();
那么它的复杂度是O(N) 而不是O(N.Log(N))。
这在任何地方都有记录吗?如果它不是“官方”的,我不想依赖这种优化。
显示 .Net Core 和 .Net Framework 之间差异的示例代码:
using System;
using System.Collections.Generic;
using System.Linq;
namespace Demo
{
static class Program
{
static void Main()
{
int[] test = { 7, 2, 4, 6, 0, 1, 6, 9, 8 };
var comparer = new Comparer();
var _ = test.OrderBy(i => i, comparer).First();
}
}
class Comparer : IComparer<int>
{
public int Compare(int x, int y)
{
Console.WriteLine($"Comparing {x} with {y}");
return x.CompareTo(y);
}
}
}
使用 .Net Framework 在线试用:https://dotnetfiddle.net/XItXYL
使用 .Net Core 在线试用:https://dotnetfiddle.net/swlc0O
.Net Framework 4.8 的输出:
Comparing 0 with 7
Comparing 0 with 8
Comparing 0 with 9
Comparing 0 with 6
Comparing 0 with 1
Comparing 0 with 0
Comparing 0 with 2
Comparing 0 with 6
Comparing 0 with 4
Comparing 0 with 2
Comparing 0 with 0
Comparing 7 with 2
Comparing 7 with 4
Comparing 7 with 6
Comparing 7 with 7
Comparing 7 with 8
Comparing 7 with 9
Comparing 7 with 6
Comparing 7 with 1
Comparing 7 with 7
Comparing 7 with 1
Comparing 9 with 7
Comparing 9 with 9
Comparing 9 with 8
Comparing 7 with 7
Comparing 7 with 8
Comparing 7 with 7
Comparing 6 with 2
Comparing 6 with 4
Comparing 6 with 6
Comparing 6 with 1
Comparing 6 with 6
Comparing 6 with 6
Comparing 6 with 1
Comparing 6 with 6
Comparing 6 with 6
Comparing 4 with 2
Comparing 4 with 4
Comparing 4 with 1
Comparing 2 with 2
Comparing 2 with 1
.Net Core 3.1 的输出:
Comparing 2 with 7
Comparing 4 with 2
Comparing 6 with 2
Comparing 0 with 2
Comparing 1 with 0
Comparing 6 with 0
Comparing 9 with 0
Comparing 8 with 0
【问题讨论】:
-
“
OrderBy后跟Count()也几乎立即运行……微软是否发明了 O(1) 排序算法?” - 引用自 this blog 在 2017 年 -
OrderBy()+Count()优化(实际上是Select()+Count())是一个完美的例子,说明了为什么这个问题很重要。阅读文章末尾附近的内容,它被确定为一项重大更改(来自Select()的副作用丢失)。有一个未讨论的修复参考,但可能会回滚优化。这也是为什么这个问题不重要的一个例子。性能指标最好使用分析和作为单元测试的一部分来处理。编写您需要编写、测试和分析的代码以识别问题并首先对其进行优化。 -
@mm8 我希望基本的排序和搜索操作能够记录其复杂性。例如,the documentation for
List<T>.Sort()声明它是一个O(N.Log(N))操作。如果没有这样的保证,我不得不使用.MaxBy()扩展名,而不是使用.OrderBy().First()。事实上,这就是我提出问题的全部理由!
标签: c# linq optimization .net-core