Min()和Max()或单个老式foreach

本文关键字:foreach 单个老 Max Min | 更新日期: 2023-09-27 18:18:55

如果我有大量的收藏,我关心性能,我应该相信奇迹和使用

var min = Y.Min();
var max = Y.Max();

或者我最好是一个好工程师,使用

var max = double.NegativeInfinity;
var min = double.PositiveInfinity;
foreach(var y in Y)
{
    if(y > max)
        max = y;
    if(y < min)
        min = y;
}

YICollection<double>,因为我需要Countforeach。我很好奇类型是否正确,因为min/max,我需要从end迭代集合,所以会有

Y.OrderByDescending((o) => o)...

Min()和Max()或单个老式foreach

Linq没有"魔法"来优化这样的查询。它所做的只是在集合上添加迭代器。Linq旨在提高编码效率,而不是原始性能。

可能在的情况下,Linq查询将比foreach执行得更快,但这不是其中之一。MinMax是两个独立的操作,因此编译器必须"提前查看"正在执行的操作,以知道它们是否可以合并到单个迭代中。没那么复杂

假设YIEnumerable<double>,那么调用Y.Max()将调用以下System.Linq.Enumerable.Max()的重载(我自己的注释,从System.Core.dll反编译的源代码):

public static double Max(this IEnumerable<double> source)
{
    if (source == null)
    {
        throw Error.ArgumentNull("source");
    }
    double num = 0.0; // current max
    bool flag = false; // is first iteration
    foreach (double num2 in source)
    {
        if (flag)
        {
            if (num2 > num || double.IsNaN(num))
            {
                num = num2;
            }
        }
        else // initialization case
        {
            num = num2;
            flag = true;
        }
    }
    if (flag) // throw if there were no elements
    {
        return num;
    }
    throw Error.NoElements();
}

作为一个一般的经验法则,如果已经有东西可以做你想做的事情-使用它-除非你观察到任何性能问题,那么你可能需要优化。

您可以尝试使用键和值相同的SortedList:

var list = new SortedList<double, double> { { 4, 4}, { 9, 9}, { 7, 7} };
var min = list.Keys[0];
var max = list.Keys[list.Count - 1];

第一个值总是最小,最后一个值总是最大。这对顺序没有多大帮助,因为它是升序的。此外,它的插入效率也不高,所以如果你关心创建它的性能(而不是从它中读取),它不是一个很好的选择。