【问题标题】:Is it better DLinq over IQueryable or DLinq over IEnumerable for better performance?DLinq 优于 IQueryable 还是 DLinq 优于 IEnumerable 以获得更好的性能?
【发布时间】:2013-08-16 17:51:59
【问题描述】:

例如,如果我与 dlinq 对抗

var custq = data.StoreDBHelper.DataContext.Customers as IEnumerable <Data.SO.Customer>;

我认为这与跑步没有太大区别:

var custq = data.StoreDBHelper.DataContext.Customers as IQueryable <Data.SO.Customer>;

因为,IQueryable 继承自 IEnumerable。

但是,如果您致电,我发现了以下内容: custq.Sum() 然后程序将在您调用 .toList() 时处理它,您使用“as IEnumerable” 因为程序上的内存提高到了相同的水平,所以当我尝试时,custq.ToList.Sum() 但不在'as IQueryable'上(因为问题随后在sql server上运行)并且不影响程序的内存使用。

我的问题很简单,你不应该在 Dlinq 上使用“as IEnumerable”吗?但是“作为 IQueryable”作为一般规则?我知道,如果您正在运行标准迭代,它会在“as IEnumerable”和“as IQueryable”之间得到相同的结果。

但仅仅是 where 语句中的汇总函数和委托表达式会有所不同 - 还是如果您使用“as IQueryable”,您通常会获得更好的性能? (用于 DLinq 实体上的标准迭代和过滤函数)

谢谢!

【问题讨论】:

  • dlinq、IQueryable 和 IEnumerable 是三个不同的东西。
  • 澄清一下 - 您是否关心内存使用方面的性能?
  • Technically Dynamic Linq 是一个建立在IQueryable interface 之上的库。 IQueryableIEnumerable 虽然在技术上连接通常意味着完全不同的东西。 Dynamic Linq,通过AsQueryable 甚至可以在IEnumerable 之上使用(参见Gravell 的response),但我从未对AsQueryable 的使用进行基准测试,个人认为它(AsQueryable)是本身几乎无用的破解,仅作为理论实验有用。
  • xanatos - 感谢您提供信息。我知道这个。我想了解使用时在引擎盖下会发生什么。过滤 .where 和 .select。等等 - 是的 - Rikalous,我想要客户端应用程序的最佳性能,所以服务器完成工作。
  • @Niklas 不,您的问题表明您不知道这一点。标题是IQueryable on Dlinq for best performance?,好像 IQueryable 是建立在 DLinq 之上的(而它恰恰相​​反......)你应该问:是 DLinq 优于 IQueryable 还是 DLinq 优于 IEnumerable 以获得更好的性能),而在问题中你有两个例子提到了IQueryableIEnumerable(没有第三个使用DLinq 的例子)

标签: c# dynamic-linq


【解决方案1】:

嗯,这取决于你想做什么...... 将其转换为 IEnumerable 将返回一个您可以枚举的对象......仅此而已。 所以是的,如果您在 IEnumerable 上调用 Count,那么您将枚举列表(因此您实际上执行了 Select 查询)并计算每次迭代。

另一方面,如果您保留一个 IQueryable,那么您可以枚举它,但您也可以执行数据库操作,如 Were、OrderBy 或 count。那么这将延迟查询的执行,并最终在运行之前对其进行修改。

在可枚举的浏览所有结果上调用 OrderBy 并在内存中对它们进行排序。在可查询对象上调用 OrderBy 只需在 SQL 末尾添加 ORDER BY 并让数据库进行排序。

一般来说,最好将其保留为 IQueryable,是的...除非您想通过实际浏览它们来计算它们(而不是执行 SELECT COUNT(*)...)

【讨论】:

  • 如果我想使用 IEnumerable,那么使用 ToList() 不是更好吗,它似乎更快?
  • 执行 ToList 实际上会执行一次 SQL 查询并在列表中查找数据。因此,它更快,因为您只去 DB 一次。现在,如果您的数据在 2 次枚举之间发生了变化,则不执行 ToList 将使您能够在执行第二次调用时检索新数据(这可能是您不关心的……这取决于您的用例)。
  • 你描述的对新数据的渴望的场景,似乎只有在同一个 DataContext 实例中添加数据时才有效,即使你多次运行 tolist(),这是我的经验。 IE。需要更新 DataContext 实例以确保包含新数据。和你一起可能会有不一样的体验?
  • 嗯,你当然是对的。我没有对此进行测试,因为我从来不需要在枚举之间刷新数据。我没有考虑数据上下文缓存。但我认为(并且没有测试)如果您完全禁用缓存,那么您将有 2 次汇总到 DB 和 2 组不同的数据。
猜你喜欢
  • 2018-09-05
  • 2021-05-10
  • 1970-01-01
  • 1970-01-01
  • 2015-01-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多