Каков расход производительности сравнения строк для INotifyPropertyChanged? - PullRequest
3 голосов
/ 03 января 2012

Мне было интересно, почему MS решила использовать строки в дизайне INotifyPropertyChanged?

Мое первоначальное беспокойство было связано с большими затратами на сравнение строк при каждом уведомлении об изменениях, и мне было интересно, должны ли имена моих свойств быть короткими, чтобы облегчить сравнение.

Однако, учитывая, что строки являются неизменяемыми в .Net, я подумал, достаточно ли интеллектуальна среда выполнения для повторного использования экземпляров строк через какую-то хеш-таблицу, поэтому сравнения фактически являются просто сравнением ссылок?

Кто-нибудь знает подробности реализации, или если нет, почему MS разработал его так, как они?

Ответы [ 6 ]

3 голосов
/ 03 января 2012

Если бы это был не string, что бы вы предложили? Это не может быть PropertyInfo, поскольку не все типы, которые поддерживают это, используют статическую типизацию - например, DataTable предоставляет модель пользовательских свойств для целей привязки, как и многие другие типы (через любой из ICustomTypeDescriptor, TypeDescriptionProvider или ITypedList).

Даже если бы это было a PropertyInfo, или даже если это было PropertyDescriptor, вы не могли бы сделать сравнение по этому вопросу: a: это заняло бы лот работы по получению справочного поиска, b: вам даже не гарантировано (для PropertyDescriptor в частности) возвращать один и тот же объект каждый раз, когда вы смотрите.

Так что это означает, что вы, вероятно, в конечном итоге сравните имя (a string) в любом случае .

Использование string позволяет вызвать это событие дешево и сравнительно дешево - сравнение строк выполняется довольно быстро, учитывая, что большинство имен свойств довольно короткие и почти все из них содержат менее 30 символов. Это будет сравнительно быстро, и это не узкое место. В большинстве случаев «что делать, теперь это изменилось» займет лот больше времени, чем это сравнение строк.

Передо мной нет реализации, но я бы надеялся , что проверка на равенство строк в основном:

  • та же ссылка? вернуть true
  • разной длины? вернуть false
  • сравнить символ за символом; вернуть ложь при первой разнице
  • вернуть true

так что это не должно быть проблемой, если все ваши свойства не имеют одинаковую длину и b: очень значительную длину

В основном: не беспокойтесь об этом.

2 голосов
/ 03 января 2012

почему MS спроектировал это так, как они?

Потому что им нужен гибкий подход, и он достаточно быстрый. При изменении свойства происходит довольно много вещей, поиск строки не будет узким местом.

Свойства зарегистрированы в некоторой базовой структуре, поиск будет похож на словарь, означающий, что HashCode обеспечит эффективный доступ. Все строки будут интернированы, но это недостаточно надежно, чтобы определить неравенство по ссылкам.

Сокращение имен свойств не принесет ощутимых улучшений, лучше использовать значимые имена.

2 голосов
/ 03 января 2012

Если вас интересуют детали реализации, вы можете использовать JustDecompile от Telerik и посмотреть, как они это сделали. Что касается того, почему строки в INotifyPropertyChanged, ответ - отражение. Я сомневаюсь, что у них есть ссылка, чтобы получить производительность для практически тривиальной задачи. Какое количество уведомлений вы говорите? Обычное приложение WPF / SL не имеет проблем с производительностью из-за сравнения строк в INotifyPropertyChanged.

2 голосов
/ 03 января 2012

Всякий раз, когда вы генерируете новую строку, она будет занимать свое собственное пространство в памяти, независимо от того, существует ли уже строка с таким же содержимым.

С другой стороны, когда вы явно присваиваете строковую переменную другой, копируется только ссылка.Использование констант - это еще один способ экономии памяти.

Повторное использование экземпляров с помощью механизма, такого как хеш-таблица, потребует гораздо больших затрат и механизмов сравнения, которые будут вызываться при создании строки.Это, вероятно, в большинстве случаев будет гораздо больше проблем с производительностью, чем просто хранить еще пару байтов.

0 голосов
/ 03 января 2012

Я думаю, что сравнение строк совсем не дорого по сравнению с другими механизмами (такими как привязки), поэтому строки определенно не являются узким местом.

Тем не менее, использование константных строк в вашем коде (я имею в виду PropertyChanged(this, new PropertyChangedEventArgs("MyProperty"))) - это быстро, но я лично предпочитаю использовать рефлексию для динамического получения имени свойства: это требует больше работы, но значительно повышает удобство сопровождения и уменьшает количество ошибок (наиболее распространенным является «Я переименовываю свое свойство, но забываю изменить параметр события PropertyChanged»).

0 голосов
/ 03 января 2012

Я бы рассмотрел потребителей - если вы сетка с привязкой к данным, у вас уже есть имя свойства в виде строки для интересующих вас столбцов. Также рассмотрите возможность вызова события - чтобы получить PropertyInfoне дешево, в то время как жесткое кодирование строки.

...