2014-12-03 58 views
0

的考慮:效率System.Linq.Enumerable.Any()

Dim values = {"First", "Second", "Third", "Fourth", "Fifth"} 
Dim searchValue = "fourth" 
Dim isPresent = False 

是不是更有效地做到這一點:

isPresent = values.Any(Function(x) String.Compare(x, searchValue, True) = 0) 

或本:

For Each value In values 
    If (String.Compare(value, searchValue, True) = 0) Then 
     isPresent = True 
     Exit For 
    End If 
Next 

基本上,我的問題是:是否Any方法短路 - 如For Each循環所做的 - 當它遇到它的第一個元素時滿足謂詞,如果是這樣的話,是否比上面顯示的操作的O(n)更快?

請注意:我的問題不是關於在字符串集合中查找字符串。我知道有很多方法可以實現這一點。我的問題比這更一般 - 關於LINQ Any方法與For Each循環方法的效率。

此外,我回顧了What is the Efficiency and Performance of LINQ and Lambda Expression in .Net?Find an item in List by LINQ?以及其他資源,他們不回答我的問題,我無法找到任何問題。

+0

是的,它應該.. – 2014-12-03 15:46:53

+0

請解釋反對票。 – 2014-12-03 15:47:23

+0

[LINQ Any vs FirstOrDefault!= null]的可能重複(http://stackoverflow.com/questions/8339988/performance-of-linq-any-vs-firstordefault-null) – 2014-12-03 15:47:38

回答

1

Enumerable.Anyimplemented as

public static bool Any<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate) { 
    if (source == null) throw Error.ArgumentNull("source"); 
    if (predicate == null) throw Error.ArgumentNull("predicate"); 
    foreach (TSource element in source) { 
     if (predicate(element)) return true; 
    } 
    return false; 
} 

所以,當項目被發現就會爆發。

除此之外,您應該使用String.Equals Method (String, String, StringComparison)重載比較忽略大小寫的等價字符串。 String.Compare對訂購更有用。

+0

@JeffMercado,謝謝你指出。編輯。 – Habib 2014-12-03 16:01:39

1

它們是完全一樣的。一旦發現一個匹配元素,Any()的實現將立即短路。

documentation

源的枚舉只要結果能夠確定停止。

+0

Thanks Will。該文檔沒有提及任何有關Any()的效率,即O(1),O(n)。我假設O(n),但仍然想知道。 – 2014-12-03 15:55:43

+0

@ roryap如果不存在匹配(最壞的情況),它總是O(n)。它只是遍歷所有元素,直到找到第一個匹配。如果第一個匹配是第一個元素,則爲O(1)(最好的情況)。 – Will 2014-12-03 16:34:57

1

反編譯Any方法,看看它做什麼...

foreach (TSource source1 in source) 
{ 
    if (predicate(source1)) 
     return true; 
} 
return false; 

你可以看到,這相當於您發佈的For Each代碼。