2011-04-06 151 views
0

當您可能擁有一個空列表時,哪種方法更好,性能更好?有關列舉空列表的性能問題

if (_myList != null && _myList.Count > 0) 
{ 
    foreach (thing t in _myList) 
    { 
    ... 

或不檢查是否_myList count包含什麼:

if (_myList != null) 
{ 
    foreach (thing t in _myList) 
    { 
    ... 

我猜有可能是在它不多,但第一個是略有更快

(?)

謝謝


編輯:

爲了澄清,我的意思是名單如下:List<Thing>

+3

我敢打賭,當你有一個空列表時,表現並不重要。 – 2011-04-06 10:25:49

+3

如果'null'和空列表之間當前沒有語義上的區別,那麼您可能需要考慮總是使用空列表來表達這種意義。它會讓你的代碼更加整潔,不必擔心空引用所有的時間... – AakashM 2011-04-06 10:26:48

+7

你是否測量了這個,發現這實際上是討論的問題?如果沒有,去測量:然後修復*做*的事情。我非常懷疑這是其中之一。否則,你會給自己溫暖舒適的感覺,改善某些東西,而不會真正使整個系統受益**。 – 2011-04-06 10:28:40

回答

3

只有回答一個性能問題的一種方法:

  1. 措施
  2. 措施
  3. 措施

你可以知道的唯一途徑:

  • 我可以提高代碼
  • 提高了代碼
  • 最重要的是:改善什麼代碼首先

是多少來衡量時間的程序的不同部分正在採取,然後再改進首要項目。爲了回答你的問題,我會假設一些額外的對象的微小開銷確實會花費你一些週期相比,只是調用計數(假設這是一個快速的調用,例如字段讀取)。

但是,由於您在問這個問題,它告訴我,您沒有足夠的關於程序狀態和代碼的信息,因此改善這種微不足道的開銷的機會實際上對用戶有着顯着的影響是如此苗條我不會打擾。

我可以保證你有更大的魚來炒作表現明智,所以先解決。

我個人並不使用null引用,除非在處理數據庫或在幾行代碼中發出信號「尚未初始化」,除此之外我使用空列表和字符串等。您的代碼更容易閱讀和理解,並且在這個級別上的微觀優化的好處將永遠不會被注意到。

+0

「只有一種方法可以回答關於表現的糟糕問題。我認爲有很好的性能問題,但不幸的是它們很罕見,並且很難:( – 2011-04-06 10:45:01

+0

很好的答案,謝謝。 – adrianos 2011-04-06 10:50:39

1

除非你調用一個緊密的循環代碼,所不同的是微不足道的。但是,請注意存在差異:對_myList.Count > 0的檢查可避免調用GetEnumerator,創建IEnumerator實現對象(堆分配)以及調用該枚舉器的方法MoveNext()

如果您在避免(堆分配+虛擬方法調用)方面性能明顯不足,可能會有所幫助,但一般來說,通過避免顯式地在_myList.Count上顯示,代碼更短且更易於理解。

+0

如果您處在這個緊張的位置,解決方案不是檢查List.Count。如果列表不是空的,會發生什麼?性能方面的考慮消失了? – 2011-04-06 10:36:06

+0

如果您必須在非常緊密的循環中檢查列表的空白,並且列表通常是空的,那麼是的,這會帶來性能優勢。然而,如果你在一個緊密的循環中檢查列表的空白,你可能是輪詢(這被認爲是邪惡的),應該考慮改用更多的事件驅動設計。 – 2011-04-06 10:39:31

1

必須免責聲明:在嘗試「優化」之前,您應該已經通過分析將其識別爲問題區域,因此您已經擁有了一個工具來快速輕鬆地確定哪些方法更快。可能性不大,對您的應用程序的性能也不會有明顯的影響。

但是,這是說,計數,爲System.Generics.Collection.List> <>幾乎肯定會更快。

雖然優化提高的東西大大(!不要害怕使用foreach的它幾乎是免費的),foreach或多或少涉及:

var enumerator = _myList.GetEnumerator(); 
try 
{ 
    while (enumerator.MoveNext()) 
    { 
    } 
} 
finally 
{ 
    enumerator.Dispose(); 
} 

這是很多不是僅僅比較簡單的更復雜屬性(安全的假設,List.Count是一個簡單的屬性)與一個常量。