为什么在这个例子中LINQ更快 [英] Why is LINQ faster in this example

查看:153
本文介绍了为什么在这个例子中LINQ更快的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我写了以下内容来测试使用 foreach vs LINQ 的性能:

  private class Widget 
{
public string Name {get;组; }


static void Main(string [] args)
{
List< Widget> widgets = new List< Widget>();
int found = 0; ()(){$ i

(int i = 0; i <= 500000 - 1; i ++)
widgets.Add(new Widget(){Name = Guid.NewGuid()。ToString );

DateTime starttime = DateTime.Now;
$ b $ foreach(小工具中的小工具)
{
if(w.Name.StartsWith(4))
found + = 1;


Console.WriteLine(found + - + DateTime.Now.Subtract(starttime).Milliseconds +ms);

starttime = DateTime.Now;
found = widgets.Where(a => a.Name.StartsWith(4))。Count();

Console.WriteLine(found + - + DateTime.Now.Subtract(starttime).Milliseconds +ms);

Console.ReadLine();
}

我得到如下输出:

 
31160 - 116ms
31160 - 95 ms

LINQ的表现胜过20%左右。这是我的理解,LINQ扩展方法使用标准的C#下盖。



那么为什么LINQ在这种情况下更快?






所以我改变我的代码使用秒表而不是日期时间,仍然得到相同的结果。如果我先运行LINQ查询,那么我的结果显示LINQ比foreach慢20%左右。这必须是某种JIT暖身问题。我的问题是我如何弥补我的测试用例中的JIT热身? 解决方案

这是因为你没有热身。如果你扭转了你的情况,你会得到相反的结果:

  31272  -  110ms 
31272 - 80 ms

开始添加热身并使用秒表以获得更好的计时。

使用热身运行测试:

  // WARM UP:
widgets.Where(a => ; a.Name.StartsWith(4))。Count();
$ b $ foreach(小工具中的小工具)
{
if(w.Name.StartsWith(4))
found + = 1;
}

//运行测试
秒表stopwatch1 =新的秒表();
stopwatch1.Start();

found = widgets.Where(a => a.Name.StartsWith(4))。Count();
stopwatch1.Stop();

Console.WriteLine(found + - + stopwatch1.Elapsed);

found = 0;
Stopwatch stopwatch2 =新的秒表();
stopwatch2.Start();
$ b $ foreach(小工具中的小工具)
{
if(w.Name.StartsWith(4))
found + = 1;
}
stopwatch2.Stop();

Console.WriteLine(found + - + stopwatch2.Elapsed);

结果:

  31039  -  00:00:00.0783508 
31039 - 00:00:00.0766299


I wrote the following to test the performance of using foreach vs LINQ:

private class Widget
{
    public string Name { get; set; }
}

static void Main(string[] args)
{
    List<Widget> widgets = new List<Widget>();
    int found = 0;

    for (int i = 0; i <= 500000 - 1; i++)
        widgets.Add(new Widget() { Name = Guid.NewGuid().ToString() });

    DateTime starttime = DateTime.Now;

    foreach (Widget w in widgets)
    {
        if (w.Name.StartsWith("4"))
            found += 1;
    }

    Console.WriteLine(found + " - " + DateTime.Now.Subtract(starttime).Milliseconds + " ms");

    starttime = DateTime.Now;
    found = widgets.Where(a => a.Name.StartsWith("4")).Count();

    Console.WriteLine(found + " - " + DateTime.Now.Subtract(starttime).Milliseconds + " ms");

    Console.ReadLine();
}

I get something like following output:

31160 - 116ms
31160 - 95 ms

In every run, LINQ outperforms foreach by around 20%. It was my understanding that the LINQ extension methods used standard c# under the covers.

So why is LINQ faster in this case?

EDIT:

So I changed my code to use stopwatch instead of datetime and still get the same results. If I run the LINQ query first then my results show LINQ to be about 20% slower then foreach. This has to be some sort of JIT warmnup issue. My question is how do I compensate for JIT warmup in my test case?

解决方案

It's because you do not have a warmup. If you reverse your cases you will get excatly the opposit result:

31272 - 110ms
31272 - 80 ms

Start adding a warmup and use a stopwatch for better timing.

Running the test with warmup:

        //WARM UP:
        widgets.Where(a => a.Name.StartsWith("4")).Count();

        foreach (Widget w in widgets)
        {
            if (w.Name.StartsWith("4"))
                found += 1;
        }

        //RUN Test
        Stopwatch stopwatch1 = new Stopwatch();
        stopwatch1.Start();

        found = widgets.Where(a => a.Name.StartsWith("4")).Count();
        stopwatch1.Stop();

        Console.WriteLine(found + " - " + stopwatch1.Elapsed);

        found = 0;
        Stopwatch stopwatch2 = new Stopwatch();
        stopwatch2.Start();

        foreach (Widget w in widgets)
        {
            if (w.Name.StartsWith("4"))
                found += 1;
        }
        stopwatch2.Stop();

        Console.WriteLine(found + " - " + stopwatch2.Elapsed);

result:

31039 - 00:00:00.0783508
31039 - 00:00:00.0766299

这篇关于为什么在这个例子中LINQ更快的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆