2012-01-03 2 views
3

왜 MS가 INotifyPropertyChanged의 디자인에서 문자열을 사용하기로 결정했는지 궁금합니다.INotifyPropertyChanged에 대한 문자열 비교의 성능 비용은 얼마입니까?

초기의 걱정은 모든 변경 알림에서 문자열 비교를 수행하는 데 드는 막대한 비용이었습니다. 비교를 돕기 위해 내 속성 이름을 짧게 유지할 것인지 궁금합니다.

그러나 문자열이 .Net에서 불변이라면 런타임이 일종의 해시 테이블을 통해 문자열 인스턴스를 재사용 할 정도로 지능적인 것인지 궁금해하기 때문에 비교는 실제로는 참조 비교 일뿐입니다.

누구든지 구현 세부 사항을 알고 있습니까, 그렇지 않은 경우 MS가 왜 그런 방식으로 설계 했습니까?

답변

3

string이 아닌 경우 무엇을 제안 하시겠습니까? 과 같이 정적 유형 지정을 지원하는 모든 유형 (, TypeDescriptionProvider 또는 ITypedList 중 하나를 통해 다른 많은 유형이 없음)과 같이 바인딩 목적으로 사용자 정의 속성 모델을 노출하기 때문에 PropertyInfo 일 수 없습니다.그것은 PropertyInfo 경우에도

, 또는 그것이 PropertyDescriptor 경우에도,이에 비교 할 수없는하십시오 : 그것은 참조 조회를 얻기 위해 작업을 많이 걸릴 것 B : 당신은 심지어 당신이 볼 때마다 똑같은 물체를 되찾기 위해 (특히 PropertyDescriptor) 보장받지 못합니다.

그렇다면 어쨌든이라는 이름 (string) 을 비교하게 될 것입니다.

string을 사용하면이 이벤트를 발생시키는 데 드는 비용이 거의 들지 않으며 비교하기가 매우 저렴합니다. 대부분의 속성 이름이 매우 짧고 거의 모든 문자가 30 문자 미만이므로 문자열 비교는 매우 빠릅니다. 그것은 놀라 울 정도로 빠르며 병목 현상이 아닙니다. 대부분의 경우 "지금 변경해야 할 작업"은 로터을이 문자열 비교 시간보다 더 오래 걸릴 것입니다.

나는 내 앞에 구현을 가지고 있지만하지 않는 나는 것 문자열 평등 검사가 기본적으로 희망 :

  • 동일한 참조? true를 반환하십시오.
  • 다른 길이? false를 반환
  • 비교 char-by-char; 첫번째 차이에서 false를 반환
  • 반환 사실 모든 속성 이름이 아니라면

그래서 그것도 문제가되지 않습니다 : 같은 길이, B :

기본적으로 매우 중요한 길이 : 그것에 대해 걱정하지 마십시오.

2

새 문자열을 생성 할 때마다 동일한 내용의 문자열이 이미 있는지 여부와 관계없이 메모리에서 자체 문자열을 차지합니다.

다른 한편으로 문자열 변수를 다른 변수에 명시 적으로 할당하면 참조 만 복사됩니다. 상수를 사용하는 것은 메모리를 절약하는 또 다른 방법입니다.

해시 테이블과 같은 메커니즘을 통해 인스턴스를 다시 사용하려면 훨씬 많은 오버 헤드와 비교 메커니즘이 필요합니다.이 메커니즘은 문자열을 만들 때마다 호출됩니다. 아마도 대부분의 경우 다른 바이트 수를 저장하는 것보다 훨씬 더 많은 성능 문제가 발생할 것입니다.

+0

인턴받은 문자열은 어떻게됩니까? –

+1

항상 그렇지는 않습니다 : http://blogs.msdn.com/b/ericlippert/archive/2009/09/28/string-interning-and-string-empty.aspx –

+0

@HarisHasan 참조는'String으로 명시 적으로 검색 될 수 있습니다. 인턴 '. –

2

구현 세부 사항에 관심이 있다면 Telerik의 JustDecompile을 사용하여 어떻게 수행했는지 확인할 수 있습니다. INotifyPropertyChanged의 문자열까지의 대답은 리플렉션입니다. 나는 그들이 실제적으로 사소한 작업을 수행하는 데 필요한 참조를 유지할 수 있을지 의심 스럽다. 당신이 말하는 알림의 양은 얼마입니까? INotifyPropertyChanged의 문자열 비교로 인해 일반적인 WPF/SL 응용 프로그램에는 성능 문제가 없습니다.

2

MS가 왜 그런 식으로 설계 했습니까?

유연한 접근이 필요하고 충분히 빠르기 때문입니다. 속성이 변경 될 때 진행되는 몇 가지 작업이 있습니다. 문자열 조회가 병목 현상이되지는 않습니다.

속성은 일부 기본 구조에 등록되어 있으므로 조회는 HashCode가 효율적인 액세스를 제공한다는 의미의 사전과 같습니다. 문자열은 모두 인턴 될 것이지만 참조에서 동등 함을 결정할만큼 신뢰할 수는 없습니다.

속성 이름을 짧게 유지해도 의미있는 이름을 사용하는 것이 좋습니다.

0

나는 소비자를 생각 하는데요 - 당신은 데이터 바인딩 된 그리드이라면, 당신은 이미 당신이 관심있는 열에 대한 문자열로 속성 이름을 가지고 또한 이벤트를 발생 고려 -. PropertyInfo이 얻을 수 싸구려가 아니라 문자열을 하드 코딩하는 것입니다.

0

문자열 비교는 다른 메커니즘 (예 : 바인딩)에 비해 비용이 많이 들지 않으므로 문자열은 병목 현상이 아닙니다.

즉, 코드에서 상수 문자열을 사용하면 (즉, PropertyChanged(this, new PropertyChangedEventArgs("MyProperty"))) 빠르지 만 개인적으로 리플렉션을 사용하여 속성의 이름을 동적으로 얻는 것이 더 좋습니다. 더 많은 작업이 필요하지만 유지 관리가 크게 향상되고 양이 줄어 듭니다. 버그 (가장 일반적인 것은 "내 재산의 이름을 변경하지만 PropertyChanged 이벤트의 매개 변수를 변경하는 것을 잊어 버렸습니다")입니다.

관련 문제