gpt4 book ai didi

c# - 为什么在 Select 之前运行 LINQ OrderBy 会花费更多时间?

转载 作者:行者123 更新时间:2023-11-30 14:44:56 24 4
gpt4 key购买 nike

在为编码问题编写解决方案时,我发现我的 LINQ 语句有一个有趣的行为。我有两种情况:

首先:

arr.Select(x => x + 5).OrderBy(x => x)

第二个:

arr.OrderBy(x => x).Select(x => x + 5)

在使用 System.Diagnostics.Stopwatch 进行一些测试后,我得到了长度为 100_000 的整数数组的以下结果。

对于第一种方法:

00:00:00.0000152

对于第二个:

00:00:00.0073650

现在我很感兴趣,为什么我先下订单会花费更多时间。我无法在谷歌上找到任何东西,所以我自己考虑了一下。

我最终得到了 2 个想法:
1. 第二种情况需要转IOrderedEnumerable,然后转回IEnumerable,而第一种情况只需要转IOrderedEnumerable,不需要转回。
2. 你最终有 2 个循环。第一个用于排序,第二个用于选择,而方法 1 在一个循环中完成所有操作。

所以我的问题是为什么在选择之前进行排序需要更多时间?

最佳答案

让我们看一下序列:

private static void UnderTestOrderBySelect(int[] arr) {
var query = arr.OrderBy(x => x).Select(x => x + 5);

foreach (var item in query)
;
}

private static void UnderTestSelectOrderBy(int[] arr) {
var query = arr.Select(x => x + 5).OrderBy(x => x);

foreach (var item in query)
;
}

// See Marc Gravell's comment; let's compare Linq and inplace Array.Sort
private static void UnderTestInPlaceSort(int[] arr) {
var tmp = arr;
var x = new int[tmp.Length];

for (int i = 0; i < tmp.Length; i++)
x[i] = tmp[i] + 5;

Array.Sort(x);
}

为了执行基准测试,让我们运行 10次数和平均值6中间结果:

private static string Benchmark(Action<int[]> methodUnderTest) {
List<long> results = new List<long>();

int n = 10;

for (int i = 0; i < n; ++i) {
Random random = new Random(1);

int[] arr = Enumerable
.Range(0, 10000000)
.Select(x => random.Next(1000000000))
.ToArray();

Stopwatch sw = new Stopwatch();

sw.Start();

methodUnderTest(arr);

sw.Stop();

results.Add(sw.ElapsedMilliseconds);
}

var valid = results
.OrderBy(x => x)
.Skip(2) // get rid of top 2 runs
.Take(results.Count - 4) // get rid of bottom 2 runs
.ToArray();

return $"{string.Join(", ", valid)} average : {(long) (valid.Average() + 0.5)}";
}

运行并查看结果的时间:

  string report = string.Join(Environment.NewLine,
$"OrderBy + Select: {Benchmark(UnderTestOrderBySelect)}",
$"Select + OrderBy: {Benchmark(UnderSelectOrderBy)}",
$"Inplace Sort: {Benchmark(UnderTestInPlaceSort)}");

Console.WriteLine(report);

结果:(酷睿 i7 3.8GHz,.Net 4.8 IA64)

OrderBy + Select: 4869, 4870, 4872, 4874, 4878, 4895 average : 4876
Select + OrderBy: 4763, 4763, 4793, 4802, 4827, 4849 average : 4800
Inplace Sort: 888, 889, 890, 893, 896, 904 average : 893

我没有看到任何显着差异Select + OrderBy似乎比 OrderBy + Select 稍微更有效率(大约 2% 的 yield ) .然而,就地排序的性能(5 )远好

关于c# - 为什么在 Select 之前运行 LINQ OrderBy 会花费更多时间?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56473565/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com