繁体   English   中英

为什么LINQ在这个例子中更快

[英]Why is LINQ faster in this example

我写了以下内容来测试使用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();
}

我得到类似以下输出:

31160 - 116ms
31160 - 95 ms

在每次运行中,LINQ都比foreach高出约20%。 据我所知,LINQ扩展方法使用了标准的c#。

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

编辑:

所以我改变了我的代码使用秒表而不是datetime仍然得到相同的结果。 如果我先运行LINQ查询,那么我的结果显示LINQ比foreach慢约20%。 这必须是某种JIT热身问题。 我的问题是如何在我的测试用例中补偿JIT热身?

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

31272 - 110ms
31272 - 80 ms

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

用预热运行测试:

        //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);

结果:

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

我做了一段时间的分析,比较以下内容:

  • 具有/不具有正则表达式的对象的LINQ

  • 带/不带正则表达式的Lambda表达式

  • 带/不带正则表达式的传统迭代

我发现LINQ,Lambda和Traditional迭代总是相同,但真正的时序差异在于Regex表达式。 只有添加正则表达式才能使评估更慢(慢一点)。 (详情请见: http//www.midniteblog.com/?p = 72

您在上面看到的可能是因为您在同一个代码块中进行了两个测试。 尝试评论一个,计时,然后评论另一个。 此外,请确保您正在运行发布版本,而不是在调试器中。

暂无
暂无

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM