2012-01-03 33 views
3

我想知道爲什麼MS決定在INotifyPropertyChanged的設計中使用字符串?INotifyPropertyChanged字符串比較的性能費用是多少?

我最初的擔心是在每次更改通知時進行字符串比較的費用很高,我想知道是否保留我的屬性名稱以縮短比較時間。

但是,考慮到字符串在.NET中是不可變的,我想知道運行時是否足夠聰明以通過某種散列表重用字符串實例,因此比較實際上只是一個參考比較?

有沒有人知道實施細節,或者如果不知道,爲什麼MS設計它的方式?

回答

3

如果不是string,你會提出什麼建議?它不可能是一個PropertyInfo,因爲不支持此使用靜態類型所有類型 - 例如,DataTable暴露結合的目的,因爲沒有許多其他類型的自定義屬性模型(通過任何的ICustomTypeDescriptorTypeDescriptionProvider,或ITypedList)。

即使一個PropertyInfo,或者即使它是一個PropertyDescriptor,你不能做這樣的比較:一:它會採取很多工作獲得參照查找,B:你甚至不能保證(特別是PropertyDescriptor)在你每次看時都能找回相同的物體。

所以這意味着,您可能最終會比較名稱(string無論如何

通過使用string,引發此事件非常便宜,而且比較便宜 - 字符串比較速度相當快,因爲​​大多數屬性名稱非常短,幾乎都少於30個字符。這將比較驚人地快速,而不是一個瓶頸。在大多數情況下,「現在該做什麼改變」​​將比該字符串比較花費更多時間lot

我沒有在我面前的實施,但我會希望該字符串平等檢查基本上是:

  • 相同的參考?返回true
  • 不同長度?返回false
  • 比較char-by-char;在第一個區別返回false
  • 還真

所以它不應該甚至是一個問題,除非你所有的屬性名稱是:相同的長度,和b:非常顯著長度

基本上是:別擔心。

2

無論何時產生一個新的字符串,它都會在內存中佔用自己的空間,不管是否已經存在具有相同內容的字符串。

另一方面,當您明確地將字符串變量分配給另一個字符串變量時,只會複製該引用。使用常量是另一種節省內存的方法。

通過類似哈希表的機制重用實例需要更大的開銷和比較機制,只要創建字符串就會調用它。這可能會在大多數情況下成爲性能問題,而不是存儲另外幾個字節。

+0

Interned的字符串呢? – 2012-01-03 12:35:32

+1

並非總是如此:http://blogs.msdn.com/b/ericlippert/archive/2009/09/28/string-interning-and-string-empty.aspx – 2012-01-03 12:36:19

+0

@HarisHasan引用可以使用String顯式檢索。 Intern'。 – 2012-01-03 12:42:44

2

如果你關心的是實現細節,你可以使用Telerik的JustDecompile,看看他們是如何做到的。 至於爲什麼字符串INotifyPropertyChanged,答案是反射。我懷疑他們保留一個參考來獲得一個實際上微不足道的任務的表現。你在說什麼通知的數量?由於INotifyPropertyChanged中的字符串比較,正常的WPF/SL應用程序沒有性能問題。

2

爲什麼MS設計它的方式呢?

因爲他們需要靈活的方法,而且速度足夠快。當一個屬性發生變化時,會發生很多事情,查找字符串不會成爲瓶頸。

這些屬性被註冊在一些基本結構中,查找將像Dictionary一樣表示HashCode將提供有效的訪問。這些字符串將全部被攔截,但是這不夠可靠,不足以從引用中確定。

保持屬性名稱短不會帶來任何可衡量的改進,更好地使用有意義的名稱。

0

我會考慮消費者 - 如果你是一個數據綁定網格,你已經擁有屬性名稱作爲你感興趣的列的字符串。還要考慮提高事件 - 獲得PropertyInfo是不便宜,而硬編碼的字符串是。

0

與其他機制(如綁定)相比,我認爲字符串比較並不昂貴,所以字符串絕對不是瓶頸。

這就是說,在代碼中使用常量字符串(我的意思是PropertyChanged(this, new PropertyChangedEventArgs("MyProperty")))速度很快,但我個人更喜歡使用反射動態獲取屬性的名稱:它需要更多的工作,但它大大提高了可維護性並減少了數量的錯誤(最常見的是「我重命名了我的財產,但我忘記更改PropertyChanged事件的參數」)。