2012-09-16 46 views
4

我正在C#中創建我的第一個網站。泛型方法vs非泛型方法 - 是否有任何性能優勢?

我注意到我在intellisense中得到了一些重複的擴展方法。進一步的調查是這兩個:

public static void ThrowNullOrEmpty<T>(this IEnumerable<T> obj, string param) 
{ 
} 

public static void ThrowNullOrEmpty(this string obj, string param) 
{ 
} 

看來字符串也可以是IEnumerable<char>

從編譯的基礎我可以刪除字符串變體,但是有任何性能問題或我應該知道的任何其他內容?

UPDATE

剛測試了1百萬次以上的迭代。

public bool IsNullOrEmpty1(string @this) 
{ 
    return String.IsNullOrEmpty(@this); 
} 

VS

public bool IsNullOrEmpty2<T>(IEnumerable<T> @this) 
{ 
    return @this == null || [email protected](); 
} 

IsNullOrEmpty1主頻自己的計算機,IsNullOrEmpty2(125 - 250毫秒)12毫秒,所以10 - 慢20倍。

在現實世界中,我每個月的迭代次數都非常高,達到每分鐘1380次(每天12小時)。兩者的結果都不到1ms。

因此,刪除IsNullOrEmpty1並不是最好的方法,但它也不是網站殺手。

+0

據我所知它是語法糖,編譯器爲您的泛型生成一個新類型。在運行時你不應該注意到一個區別。 – BenCr

+3

這麼容易測量,但除非它是一個問題,爲什麼要麻煩? – spender

回答

3

它可能取決於這些方法的實現 - 字符串版本可以優化性能,而IEnumerable<T>人需要更一般。調用泛型方法沒有開銷,它在編譯時已經被解析爲正確的泛型參數。

字符串版本可以像這樣,它具有非常小的開銷來實現(它基本上需要做出兩個比較):

if (String.IsNullOrEmpty(value)) 

在另一方面,IEnumerable<T>可能實現的問題是這樣的:

if (value == null || !value.Any()) 

這裏的關鍵是Any調用,它將調用GetEnumerator方法並返回一個枚舉器。 (爲了簡單起見,我們將忽略框架可能在某些類型內部使用的性能優化)。這意味着實現實際上創建了一個新的對象,稍後需要進行垃圾回收 - 兩者都需要更多的時鐘週期,而不是在string版本中提到的兩個比較。

實際上,除非這些方法被稱爲非常頻繁,否則我懷疑是否有任何顯着的性能差異。

順便說一句,這個工程的原因是,string是一個IEnumerable<char>

0

string是一個密封類,所以我們可以直接調用string類中的方法而不訪問虛函數指針。 理論上說,它比傳遞I Enumerable<char>更快。但實際上,這取決於您在方法中調用string方法的次數。