简体   繁体   English

为什么这个Linq表达式比另一个表达式慢很多?

[英]Why is this Linq expression so much slower than the other?

Time of execution: foo(1) >>> foo(2) >> foo(3) 执行时间:foo(1)>>> foo(2)>> foo(3)

roughly: 1427349 >>> 14757 >> 1362 大约:1427349 >>> 14757 >> 1362

foo(3) is the most optimized algorithm among the three, so I'm not surprised it's the fastest. foo(3)是这三种算法中最优化的算法,所以我并不惊讶它是最快的。 What's surprising to me is that foo(2) is so much faster than foo(1). 让我惊讶的是,foo(2)比foo(1)快得多。 My impression is that foo(2) sorts, while foo(1) is operating similarly to foo(3). 我的印象是foo(2)进行排序,而foo(1)的操作与foo(3)相似。 May I know what is the cause the slowdown for foo(1)? 我可以知道foo(1)变慢的原因是什么? Show me what's under the hood. 告诉我幕后情况。 Thanks! 谢谢!

void Main()
{   
    Random r = new Random();
    for(int i = 0; i < array.Length; i++)
    {
        array[i] = new A(r.Next(int.MaxValue));
    }   

    foo(1); 
    foo(2);
    foo(3); 
}

A[] array = new A[10000];
static Stopwatch sw = new Stopwatch();

public void foo(int s)
{
    sw.Reset();
    sw.Start();

    switch(s)
    {
        case 1:
            array.First(x => (x.value == array.Max(y => y.value))).Dump();
            break;
        case 2:
            array.OrderBy(x => x.value)
            .Last()
            .Dump();    
            break;
        case 3:
            {           
                int max = array[0].value;
                int index = 0;
                int i = 0;
                for(; i < array.Length; i++)
                {
                    if(array[i].value >= max)
                    {
                        max = array[i].value;
                        index = i;
                    }
                }
                array[index].Dump();
            }
            break;
    }

    sw.Stop();
    sw.Dump();
}
class A
{
    public int value;
    public A(int value)
    {
        this.value = value;
    }
}

Code testing was in linqpad, so you can ignore the .Dump() method. 代码测试在linqpad中进行,因此您可以忽略.Dump()方法。

The first is O(N²), because you iterate over the array once for each outer iteration. 第一个是O(N²),因为您需要为每个外部迭代对数组进行一次迭代。 The second is O(N log N), because you are sorting first. 第二个是O(N log N),因为您先排序。 The last is O(N), because you iterate over the array in a single pass with no loop inside each iteration. 最后一个是O(N),因为您可以一次遍历数组,并且每次迭代都没有循环。

Try this: 尝试这个:

        case 1:
            var max = array.Max(x => x.value);
            array.First(x => x.value == max).Dump();
            break;

It should now be comparable with the third case, though not quite, since you have to traverse the array 1.5 times, on average (assuming only one element has the max value). 现在,它应该可以与第三种情况相提并论,尽管不尽相同,因为平均而言,您必须遍历数组1.5次(假设只有一个元素具有最大值)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 为什么HashSet <Point>比HashSet <string>慢得多? - Why is HashSet<Point> so much slower than HashSet<string>? 为什么我的正则表达式比编译时编译得慢得多? - Why is my regex so much slower compiled than interpreted? 为什么MultiFieldQueryParser比手动创建查询要慢得多? - Why is MultiFieldQueryParser so much slower than creating query by hand? 为什么异步代码比同步代码慢得多 - Why asynchronous code is so much slower than synchronous code 为什么D中的for循环比C#中的for循环慢得多? - Why are for loops in D so much slower than for loops in C#? 为什么运算符比方法调用慢得多? (结构在较旧的JIT上较慢) - Why are operators so much slower than method calls? (structs are slower only on older JITs) 为什么在C ++中这么慢? - Why is this so much slower in C++? 为什么 Func&lt;&gt; 委托这么慢 - Why are Func<> delegates so much slower 为什么这个 Linq 在 IEnumerable 上聚合<class.primitive> & I 可枚举<struct.primitive>比 IEnumerable 慢得多<primitive></primitive></struct.primitive></class.primitive> - Why is this Linq Aggregate on IEnumerable<Class.primitive> & IEnumerable<Struct.primitive> much slower than IEnumerable<primitive> 为什么F#比C#慢得多? (素数基准) - Why is F# so much slower than C#? (prime number benchmark)
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM