【问题标题】:Performance of foreach vs. Where().Select()foreach 与 Where().Select() 的性能
【发布时间】:2018-10-09 14:48:44
【问题描述】:

这个问题是关于从性能角度比较 foreach 和 Linq 方法的。
下面我带来的代码只是我目前的一个例子。


与 foreach 循环相比,使用 .Where().Select() 是否有优势(从性能的角度来看)?

我有这个 C# 块,我想在这里提高性能:

var resultList = new List<MyItemWrapper>();
foreach (var key in KeysCollection)
{
    if (SomeCondition(key))
    {
        var anotherKey = CreateAnotherKey(key);
        if (AnotherCondition(anotherKey))
        {
            resultList.Add(new MyItemWrapper { Id = key });
        }
    }
}

我曾尝试使用 Where().Select() 并且也尝试过使用 AsPArallel() 但性能没有任何改进。相反,我发现性能越来越差。

var resultList = KeysCollection
                    .Where(key =>
                    {
                        if (!SomeCondition(key))
                            return false;

                        var anotherKey = CreateAnotherKey(key);
                        return AnotherCondition(anotherKey);
                    })
                    .Select(key => new MyItemWrapper { Id = key })
                    .ToList();

注意事项:

  • SomeCondition()AnotherCondition() 应被视为黑盒。
  • 返回的resultList 应该是IList
  • KeysCollection 的类型为 ICollection

有人可以帮忙并给出改进的建议吗?

【问题讨论】:

  • 您是否通过分析器运行代码以查看瓶颈在哪里?你要处理多少把钥匙?也许慢是在其中一种黑盒方法中,在这种情况下,您的循环构造不会产生任何影响。
  • 看起来你可以简单地使用github.com/dotnet/BenchmarkDotNet并将结果发布到这个问题中
  • Linq 方法本质上只是调用foreach 循环,你为什么认为它会执行得更好?我想CreateAnotherKey() 和/或AnotherCondition() 是瓶颈......
  • 感谢所有 cmets。我的主要问题是关于 foreach 与 LINQ 方法的性能。如果其中任何一个比另一个有任何明显的优势。与黑盒方法无关。应该允许我们并行运行的 AsParallel() 怎么样?为什么它也没有帮助?我也试过了。

标签: c# performance foreach


【解决方案1】:

Linq 并非旨在提高性能。它旨在提高编码效率。在某些情况下,它可能比 bad 循环更高效(例如,当您查找某个项目的存在时,Any 将在找到一个项目时停止,但一个坏循环可能会继续循环),但一般不会提高性能。

因此,使用您更好理解的任何内容(恕我直言,您使用的委托更难以理解)并使用 Linq 来提高可读性。

如果您发现性能问题,那么请使用一个好的分析器来确定花费最多时间的地方。如果 Linq 方法实际上是一个瓶颈,我会感到惊讶。

也就是说,您可以这样构造查询:

var reslutList = KeysCollection.Where(key => SomeCondition(key))
                               .Where(key => AnotherCondition(CreateAnotherKey(key)))
                               .Select(key => new MyItemWrapper { Id = key })
                               .ToList();

哪个可能比循环或自定义委托更容易理解。

【讨论】:

  • 非常感谢您的明确回答。所以听起来是这样的:“使用 LINQ 在性能方面没有优势,但更利于可读性”。这是一个正确的说法吗?但是应该允许我们并行运行的 AsParallel() 呢?为什么它也没有帮助?我也试过了。
  • AsParallel 仅有助于 CPU 绑定 进程。如果您的进程没有与 CPU 挂钩,但存在其他瓶颈(内存、I/O、网络等),那么AsParallel 可能无济于事。
猜你喜欢
  • 1970-01-01
  • 2014-01-03
  • 1970-01-01
  • 2013-08-19
  • 2021-12-05
  • 2011-03-13
  • 2011-11-29
  • 2020-06-03
  • 2018-01-26
相关资源
最近更新 更多