Min()和Max()或单个oldschool foreach?

时间:2014-08-21 13:16:19

标签: c# linq

如果我有大收藏并且我关心表现,我应该相信奇迹并使用

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。我很好奇,如果类型是正确的,因为最小/最大,我将需要从最后迭代集合,所以会有

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

3 个答案:

答案 0 :(得分:4)

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

可能是案例,其中Linq查询的执行速度比foreach快,但这不是其中之一。 MinMax是两个独立的操作,因此编译器必须&#34;向前看&#34;查看正在执行哪些操作以了解它们是否可以合并为单个迭代。它并不复杂。

答案 1 :(得分:1)

假设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();
}

作为一般的经验法则,如果某些东西已经存在,你可以做什么 - 使用它 - 除非你观察到任何性能问题,否则你可能需要进行优化。

答案 2 :(得分:1)

您可以尝试使用Key和Value相同的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];

第一个值始终为最小值,最后一个最大值。因为它是递增的,对订单没有多大帮助。此外,插入它的效率不高,如果你关心创建它的性能(而不是从中读取),它就不是一个很好的选择。