Where()。Count()与Count()

时间:2014-01-21 08:20:14

标签: vb.net performance linq list

以下是我班级相关部分的摘录,该部分继承自List(Of T)。查看SelectedObjectsSelectedCount属性。我出于性能原因添加了SelectedCount,但我现在想知道它是否比SelectedObjects.Count()更好。

Public Class DrawingObjectsList
    Inherits List(Of DrawingObjectBase)

  Friend ReadOnly Property DOsOfCurrentFace As IEnumerable(Of DrawingObjectBase)
    Get
        Return Me.Where(Function(DObj) DObj.Face = mFace)
    End Get
  End Property

  Public ReadOnly Property SelectedObjects() As IEnumerable(Of DrawingObjectBase)
    Get
        Return DOsOfCurrentFace.Where(Function(DObj) DObj.IsSelected = True)
    End Get
  End Property

  Public ReadOnly Property SelectedCount() As Integer
    Get
        Return DOsOfCurrentFace.Count(Function(DObj) DObj.IsSelected = True)
    End Get
  End Property
End Class

我的理论是Where(predicate).Count()Count(predicate)都需要迭代List,因此不应该有任何相当大的差异。此外,由于我未在ToList()上执行任何ToArray()Where(),因此我不确定在其上调用Count()是否可以利用内置{ {1}}属性与否。

我应该保留还是删除Count属性?

2 个答案:

答案 0 :(得分:0)

正如Jon Skeet在评论中所说,最好的方法是衡量。 但是,如果您 使用SelectedObjects,我会删除CountObjects。原因如下:

  • 如果您的IEnumerable是内存列表,那么当您提到CountObjects时,将再次浏览原始列表。如果您已经调用SelectedObjects并将结果保存在变量中,则调用Count将只调用列表中的属性并立即为您提供对象数,而无需再次循环。如果您还没有拨打SelectedObjects,那么我认为调用.Where(...).Count() 比<{1}} 更慢。这是你应该测试的东西。

  • 如果您.Count(...)IEnumerable,那么它已经实现了,在这种情况下无关紧要,或者 - 如果它没有实现 - 那么我希望对IQueryable的来电将转换为.Where(...).Count()将会发出的SELECT COUNT(*)查询。同样,这是你应该测试的东西。

答案 1 :(得分:0)

我用一些(相当幼稚的)代码计时:

Dim r = New Random()
Dim sw As Stopwatch
Dim list = Enumerable.Range(0, 100000000).Select(Function(x) r.Next)

sw = Stopwatch.StartNew()
list.Count(Function(x) x Mod 2 = 0)
Console.WriteLine(sw.ElapsedMilliseconds)

sw = Stopwatch.StartNew()
Dim x = list.Where(Function(x) x Mod 2 = 0).Count()
Console.WriteLine(sw.ElapsedMilliseconds)

我得到的结果是

Count   Where/Count
-------------------
3494    3624
3484    3612
3523    3617
3522    3609
3500    3623
3493    3631
3536    3620
3541    3682
3621    3633
3515    3686   

平均而言,使用Where/Count需要大约4%的时间(在这种情况下平均增加110毫秒)。因此可能只是Count的性能优势。但是,您首先要确认在特定方案/环境中是否成立。看看Eric Lippert的C# Performance Benchmark Mistakes,了解如何做到这一点的好方法。