Sinatr
Sinatr

Reputation: 21998

Min() and Max() or single oldschool foreach?

If I have big collection and I care about performance, should I believe in miracle and use

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

or I better be a good engineer and use

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

Y is ICollection<double>, because I need Count and foreach. I am curious if type is right, because of min/max and that I will need to iterate collection from end, so there will be

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

Upvotes: 5

Views: 1401

Answers (3)

Mant101
Mant101

Reputation: 2747

You could try a SortedList with the Key and Value being the same:

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

First value will always be the min, last the max. Doesn't help much with the order by as it is ascending. Also, its not very efficient to insert into so if you care about performance of creating it (as opposed to reading from it) it isn't such a great choice.

Upvotes: 1

dav_i
dav_i

Reputation: 28137

Assuming that Y is IEnumerable<double> then calling Y.Max() for example will call the following overload of System.Linq.Enumerable.Max() (comments my own, source decompiled from 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();
}

As a general rule of thumb, if something already exists to do what you want - use that - unless you observe any performance issues then you may need to optimise.

Upvotes: 1

D Stanley
D Stanley

Reputation: 152626

There's no "magic" to Linq that will optimize queries like that. All it does is add iterators on top of the collections. Linq is designed to improve coding efficiency, not raw performance.

There may be cases where a Linq query will perform faster than a foreach, but this isn't one of them. Min and Max are two separate operations, so the compiler would have to "look ahead" to see what operations are being done to know whether they could be combined into a single iteration. It's not that sophisticated.

Upvotes: 5

Related Questions