查找具有最大值属性的元素的速度更快

23 浏览
0 Comments

查找具有最大值属性的元素的速度更快

通常,我会这样找到具有最大值属性的元素:

var itemWithMaxPropValue = collection.OrderByDescending(x => x.Property).First();

但从性能的角度来看,这种方法好吗?也许我应该像这样做:

var maxValOfProperty = collection.Max(x => x.Property);
var itemWithMaxPropValue = collection
                                 .Where(x => x.Property == maxValueOfProperty).First();

0
0 Comments

在查找具有最大值属性的元素中,使用Max会更快速,因为它专门设计用于此目的。排序以查找最大值似乎太过繁琐。

此外,对于查找最大值,我不会使用Where,而是使用Single - 因为我们在这里只需要一个Single值。

var maxValOfProperty = collection.Max(x => x.Property);
var itemWithMaxPropValue = collection
                            .Single(x => x.Property == maxValueOfProperty);

或者,如果集合包含最大值的重复项,则可以使用First

var maxValOfProperty = collection.Max(x => x.Property);
var itemWithMaxPropValue = collection
                            .First(x => x.Property == maxValueOfProperty);

或者,根据Kathi的建议,使用MoreLINQ,可以使用MaxBy来实现:

var itemWithMaxPropValue = collection.MaxBy(x => x.Property);

请参考此帖子,Jon Skeet的答案。

如果集合包含多个具有最大值属性的项,而OP不关心选择哪个项,则可能希望使用First而不是Single

你是对的,这确实是一个有效的替代方案。

还请注意,如果将两行代码组合在一起,collection.Max(x => x.Property)可能会被多次计算。

你是指这个:msdn.microsoft.com/en-us/library/…吗?它似乎并不是典型的LINQ,我不确定它的性能如何...

如果那是MoreLINQ,那就是我所指的,但是也请查看这个:stackoverflow.com/a/1101931/5210934,你会在那个答案中找到MaxBy(..)的内容。

好的,我提供了这个替代方案,并引用了你的建议。;) 它似乎是一个很好的解决方法。感谢你的指出。

从数学上讲,使用聚合-解决方案似乎是最好的,因为您只需遍历列表一次...

忽略它引起的所有其他延迟,那可能是的。;) 只是稍微复杂一些,需要仔细观察...

0
0 Comments

在上述内容中,出现了一个关于找到具有最大属性值的元素哪种方法更快的问题。第一种方法涉及对整个集合进行排序,而第二种方法需要遍历集合两次。但是,你可以在不排序集合的情况下一次性找到具有最大属性值的项。在MoreLINQ库中有一个MaxBy扩展方法可以实现相同的功能。或者你可以自己实现相同的功能,如下所示:

public static TSource MaxBy(this IEnumerable source, Func selector)
{
    // 检查参数
    using (var iterator = source.GetEnumerator())
    {
        if (!iterator.MoveNext())
            throw new InvalidOperationException();
        var max = iterator.Current;
        var maxValue = selector(max);
        var comparer = Comparer.Default;
        while (iterator.MoveNext())
        {
            var current = iterator.Current;
            var currentValue = selector(current);
            if (comparer.Compare(currentValue, maxValue) > 0)
            {
                max = current;
                maxValue = currentValue;
            }
        }
        return max;
    }
}

使用方法很简单:

var itemWithMaxPropValue = collection.MaxBy(x => x.Property);

通过使用MaxBy方法,你可以在不排序整个集合或遍历集合两次的情况下,找到具有最大属性值的元素。这种方法更高效。

0
0 Comments

在这段内容中,出现了一个关于查找具有最大值属性的元素速度的问题。根据内容中的解释,排序的时间复杂度为N * log (N),而查找最大值只需要N的时间复杂度,所以查找最大值的速度更快。然而,内容中提到的问题是Linq库中并没有提供查找最大值的函数,所以建议实现一个名为ArgMax的函数来解决这个问题。下面是一个实现ArgMax函数的示例代码:

public static class EnumerableExtensions {
    public static T ArgMax(this IEnumerable source, 
                                 Func map, 
                                 IComparer comparer = null) {
        if (Object.ReferenceEquals(null, source))
            throw new ArgumentNullException("source");
        else if (Object.ReferenceEquals(null, map))
            throw new ArgumentNullException("map");
        T result = default(T);
        K maxKey = default(K);
        Boolean first = true;
        if (null == comparer)
            comparer = Comparer.Default;
        foreach (var item in source) {
            K key = map(item);
            if (first || comparer.Compare(key, maxKey) > 0) {
                first = false;
                maxKey = key;
                result = item;
            }
        }
        if (!first)
            return result;
        else
            throw new ArgumentException("Can't compute ArgMax on empty sequence.", "source");
    }
}

通过使用上述的ArgMax函数,可以简单地实现以下代码来查找具有最大属性值的元素:

var itemWithMaxPropValue = collection
    .ArgMax(x => x.Property);

通过实现ArgMax函数,我们可以更快地找到具有最大属性值的元素。

0