.net - 为什么 IEnumerable 比 IQueryable 快?

标签 .net performance entity-framework ienumerable iqueryable

介绍

我一直在研究两者之间的区别。我决定亲自动手测试它们,因为我想了解两者之间的性能差异(如果有的话)并了解原因

我创建了一个简单的控制台应用程序。我正在使用 Entity Framework 和 SQL Server。我创建了一个指向数据库表的模型。该表有大约 1000 条记录。

测试

Dim _db As New SampleEntities
Dim sw As New Stopwatch

测试 1 - 966 毫秒

Dim allMemos As IEnumerable(Of Memo) = _db.Memos
sw.Start()
allMemos.ToList()
sw.Stop()

测试 2 - 6 毫秒

Dim iEnum As IEnumerable(Of Memo) = _db.Memos.AsEnumerable
sw.Restart()
iEnum.Where(Function(f) f.Active).ToList()
sw.Stop()

测试 3 - 186 毫秒

Dim iQuer As IQueryable(Of Memo) = _db.Memos.AsQueryable
sw.Restart()
iQuer.Where(Function(f) f.Active).ToList()
sw.Stop()

我的发现

在我开始之前,我的研究告诉我,在许多情况下,IQueryable 更快,因为它可能会优化查询,以便过滤器(即备忘录 Active)由 SQL 执行,因此非常调用 ToList() 时将返回很少的结果。

然而,我的发现却恰恰相反。为什么?我确信在我的测试中 IQueryable 更快。我特意设置它来显示这一点。

“这是因为你使用了iQuer As IQueryable(Of Memo)!”

我也是这么想的。我听说将我的对象转换为 IQueryable 可能不好,因为它无论如何都必须从 IEnumerable 转换。所以我尝试了这个:

Dim iQuer As IEnumerable(Of Memo) = _db.Memos.AsQueryable

而且它确实提高了性能,因此测试 3 用了 17 毫秒而不是 186 毫秒。但它仍然比 6ms 慢(测试 2)。

这是怎么回事?

最佳答案

我不知道 _db.Memos 返回什么,但在测试 2 中

Dim iEnum As IEnumerable(Of Memo) = _db.Memos.AsEnumerable

所有的记录都可以被加载到内存中。

在测试 3 中,调用 ToList 时加载记录:

  iQuer.Where(Function(f) f.Active).ToList()

你应该做两件事:

  1. 在分配之前移动秒表线,然后比较结果。
  2. 在您的数据库中设置跟踪以查看代码实际访问数据库的位置。

关于.net - 为什么 IEnumerable 比 IQueryable 快?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17181736/

相关文章:

algorithm - k-way合并中合并和项目数之间的关系是什么

c# - 如何处理 Entity Framework 中的陈旧缓存?

.net - 针对 "Any CPU"的 .NET 应用程序能否在多个环境中使用 P/Invoke 调用?

c# - 如何在 ASP.NET 中使用插件架构?

mysql - 两个表之间的查询

c# - 如何重写此 Linq 查询以避免使用 FirstOrDefault?

entity-framework - EF/Silverlight 应用程序的项目结构

c# - Entity Framework 错误 : The field "ForeignKey" is required EF

javascript - jQuery 性能 : Chain appends or append multiple arguments?

c++ - STL:从A到B的自然数集