2014-01-21 111 views
3

下面是繼承自List(Of T)的我的課程相關部分的摘錄。看看SelectedObjectsSelectedCount屬性。由於性能原因,我添加了SelectedCount,但我現在想知道它是否比SelectedObjects.Count()更好。Where()。Count()vs. 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)將需要遍歷列表,因此不應該有任何相當大的差異。此外,由於我沒有在Where()上做任何ToList()ToArray(),我不確定是否可以調用Count()就可以利用內置的Count屬性。

那麼我應該保留還是刪除SelectedCount屬性?

+1

如果您想知道是否因性能原因而做某件事情值得,那麼有一個明顯的方法可以找到:衡量它。 –

+0

@JonSkeet:正確,但我也想讓專業人士評估我的理論。 – dotNET

+1

那麼,爲什麼你不測量*現在*,並將其添加到問題中......以及試圖確定'Count'在你的應用程序中所花費的時間是否真的很重要。 –

回答

0

正如Jon Skeet在評論中所說,找出最好的方法是衡量。 但是,如果您是使用SelectedObjects,我會刪除CountObjects。其原因如下:

  • 如果您IEnumerable是在內存中的列表,然後根據你提到CountObjects將通過原始列表一次。如果您已經撥打SelectedObjects並將結果放入一個變量中,則調用Count將僅調用列表中的一個屬性,並立即爲您提供對象的數量,而無需再次循環。如果你還沒有撥打SelectedObjects那麼我認爲.Where(...).Count()不是.Count(...)。這是你應該測試的東西。

  • 如果IEnumerableIQueryable然後要麼已經實現,在這種情況下,它並不重要,或者 - 如果它沒有被物化 - 那麼我希望.Where(...).Count()通話將轉換成同一SELECT COUNT(*)查詢.Count(...)會。再次,這是你應該測試的東西。

+0

在'IQueryable'的情況下,認識到'.Where'方法和'.Count'方法在這些方面是非常重要的。依賴於繼承/多態會導致。淨加載你的表,然後計數對象。 – Aron

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,瞭解如何做到這一點的好技巧。