在构造LINQ表达式时(对我来说,linq到对象)有许多方法可以完成某些事情,有些方法比其他方法更好,更好,更有效.
是否有一种"调整"或优化这些表达式的好方法?
人们使用什么基本指标,你如何收集它们?
有没有办法获得"总迭代次数"或其他一些指标,你可以"知道"更低意味着更好?
编辑
感谢Richard/Jon的回答.
看起来我真正想要的是为LINQ表达式获取一个简单的Operation Count"OCount",虽然我不确定LINQ中是否存在钩子以允许它.假设我具有特定机器硬件(SLA)的目标性能级别.理想情况下,我会添加一个单元测试来确认通过该查询移动的典型数据将在指定的时间内(来自SLA)进行处理.问题是这将在构建服务器/开发人员机器/等上运行.这可能与SLA的机器硬件几乎没有相似之处.因此我的想法是,我将确定表达式的可接受的最大"OCount",知道如果OCount小于X,它肯定会在目标"典型"硬件上的SLA下提供可接受的性能.如果OCount超过此阈值,构建/单元测试会产生警告.理想情况下,我想有这样的东西(pseudocode-ish):
var results = [big linq expression run against test dataset]; Assert.IsLess(MAXALLOWABLE_OCOUNT, results.OCount)
其中results.OCount只是给我生成结果集所需的总迭代次数(n).
我为什么喜欢这个?
好吧,即使是中等大小的LINQ表达式,由于增加了整体操作次数,一小部分更改/添加也会对性能产生巨大影响.应用程序代码仍将通过所有单元测试,因为它仍然会产生正确的结果,但在部署时工作速度很慢.
另一个原因是简单的学习.如果你做了什么并且OCount上升或下降了一个数量级,那么你就会学到一些东西.
编辑#2 我也会提出一个潜在的答案.它不是我的,它来自Cameron MacFarland来自另一个问题,我问这个产生了这个问题.事实证明,我认为这个问题的答案可以在单元测试环境中工作,就像我在第一次编辑这个问题时描述的那样.
它的本质是在单元测试夹具中创建测试数据集,您可以按照本答案中概述的方式将其输入LINQ表达式,然后将迭代计数相加并与最大允许迭代计数进行比较.
请参阅Cameron的答案
你基本上需要解决复杂性功能.这取决于操作员,但遗憾的是,它不会被很好地记录.
(对于一般原则,我同意Richard的回答 - 这只是LINQ to Objects的东西.)
如果您有特定的操作员,那么您可能会对它们有所了解,但最重要的是:
选择= O(n)
其中= O(n)
加入= O(内部+外部+匹配)(即它不比它便宜inner + outer
,但可能inner * outer
与结果一样糟糕)
GroupJoin =与Join相同,但是缓冲而不是外部流式传输
OrderBy = O(n log n)
SelectMany = O(n +结果)
Count = O(1)或O(n)取决于它是否实现IList
计数(谓词)= O(n)
最大/最小= O(n)
全部/任何= O(n)(可能早出)
区别= O(n)
Skip/Take = O(n)
SkipWhile/TakeWhile = O(n)
确切的特征取决于运营商是否缓冲或流.