【问题标题】:Why is IEnumerable faster than IQueryable?为什么 IEnumerable 比 IQueryable 快?
【发布时间】:2013-06-15 10:14:21
【问题描述】:

简介

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

我创建了一个简单的控制台应用程序。我正在使用实体框架和 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 - 6ms

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 更快,因为它可能会优化查询,以便由 SQL 执行过滤器(即 memo 是Active),因此返回的结果很少当ToList() 被调用时。

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

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

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

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

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

这是怎么回事?

【问题讨论】:

  • 男孩,人们会喋喋不休地谈论你的“性能”测试。做好准备。
  • 没关系。这就是我学习的方式:D
  • @RowanFreeman 我建议你用几百万行再试一次。 1000 行的性能测试算不上性能测试。
  • 确实如此,并且部分回答了我的问题,即“我做错了什么?”

标签: .net performance entity-framework ienumerable iqueryable


【解决方案1】:

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

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

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

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

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

你应该做两件事:

  1. 在作业前移动秒表行,然后比较结果。
  2. 在您的数据库中设置跟踪以查看代码实际到达数据库的位置。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-09-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-10
    • 2011-01-26
    • 2019-11-02
    相关资源
    最近更新 更多