2013-04-14 3 views
-1

객체가 불변 인 경우 (내 구현 객체) 길이에 대한 속성 또는 읽기 전용 변수를 사용해야합니까? object의 길이가 속성 인 경우 for 루프에서 일부 성능이 손실됩니다.불변 객체의 길이 속성

for (int i = 0; i < myObject.Length; i++) // Length is readonly variable 
{ 
    // some code 
} 

과 :

int len = myObject.Length; // Length is a property 

for (int i = 0; i < len; i++) 
{ 
    // some code 
} 

당신은 무엇을 제안합니까?

+1

속성으로 인해 성능이 저하된다는 것을 측정하셨습니까? 'get '도구는 일반적으로 JIT 컴파일러에 의해 인라이닝되기에 충분히 간단하므로 필드와 속성간에 성능 차이는 없습니다. – dtb

+0

작업 : for 루프와 함께 바이트 *를 사용하여 메모리를 지 웁니다. 개체에서 변수 사용 = X ms. 속성 사용 = 2 * X ms. 그래서 재산은 훨씬 더 느립니다. 객체 변수에서 Length를 로컬 변수에 복사하면 또 다른 10 %의 속도가 나타납니다. 그래서 마침내 Length 속성을 사용하고 각 for 루프 앞에 로컬 변수에 값을 복사합니다. 물론 메모리를 지우려면 long *을 사용할 때 길이를 로컬 변수에 복사하는 것이 더 유용 할 것입니다. 그래서 나는 그것을 해결했다. – zgnilec

답변

0

임시 변수를 쿼리로 변경하는 것은 꽤 표준적인 리펙터입니다. 즉, 속성 호출이 매우 빠르다면 임시 변수를 만들어서는 안됩니다. 이를 'replaceTempWithQuery'라고합니다. 난 강력하게 프로그래밍을하지 모든 사람에게이 책 리팩토링을 추천 할 것입니다

http://www.refactoring.com/catalog/replaceTempWithQuery.html

: 여기에 선전이다.

EDIT로 추가 :이 문제에 대해 downvoted가되었지만 조기 최적화는 실제로 방지해야 할 항목입니다. 매우 심각한 문제가 발생하는 경우 temp로 쿼리를 수정하는 것이 좋습니다.

A famous quote from Donald Knuth: "We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil". 그럼에도 불구하고 많은 코드 관리자를 보유하지 않는 한 선택의 문제입니다. 그런 다음 유지 관리 시간이 최적화/설계 선택에 중요한 영향을 미칩니다.

1

여기에 매우 큰 특수 데이터 세트가 없으므로 루프의 반복 횟수가 많을 것으로 예상되므로 속성과 변수의 차이는 거의 무시할 수 있습니다.

간단한 옵션은 변수와 함께가는 것입니다. 속성을 사용하면 클래스의 서명을 변경하지 않고 나중에 동작을 수정할 수있는 추가 이점을 얻을 수 있습니다 (예를 들어 길이를 새로운 방식으로 계산하려는 경우).

또 다른 관련 이점은 개인적으로 속성을 설정하는 기능 (필요할 경우 나중에 변경)이지만 공개적으로 만 읽을 수있는 기능입니다.

나는 이러한 이유로 인해 부동산에 갈 것이라고 가정합니다. 어쨌든 나는 성능에 대한 기대 효과만을 토대로이 선택을하지는 않을 것입니다.

3

그런 샘플에서 중요한 것은 없습니다. 단순한 get에 들어있는 JIT의 가능성은 매우 낮습니다. get이 인라인되지 않은 경우에도 추가 함수 호출이 매우 단순한 코드 외부에서 성능 병목 현상을 일으키지는 않습니다.

무슨 뜻인지 보여주기 위해 릴리스 모드에서 다음을 실행했습니다 (디버그 상태로두면 다르게 작동합니다).

private int Length { get; set; } 
private int _length; 
void Run() 
{ 
    Length = int.MaxValue; 
    _length = int.MaxValue; 
    var watch = new Stopwatch(); 
    watch.Start(); 
    for (int i = 0; i < Length; i++) 
    { 
    } 
    watch.Stop(); 
    Console.WriteLine("Elapsed: {0}ms", watch.ElapsedMilliseconds); 
    watch.Restart(); 
    for (int i = 0; i < _length; i++) 
    { 
    } 
    watch.Stop(); 
    Console.WriteLine("Elapsed: {0}ms", watch.ElapsedMilliseconds); 
} 

다음과 같은 평균값이 있습니다. 속성 : 743 ms, 변수 : 740 ms. 그 차이는 아마도 시도 횟수가 적어서 내 컴퓨터에서 다른 일이 일어나기 때문일 수 있습니다.

이제 특성을 통해 인라인을 해제하면 속성에 4577 ms, 변수에 775 ms의 시간 차이가 발생합니다. 이제 막 큰 차이 (6 배 많은 시간 합계)가 들리지만 내 루프 조건 인 20 억 반복을 기억하십시오. 즉, 차이는 작동 당 2 ns와 같습니다. 즉, 약 4 클록 주기로, 가장 극단적 인 성능 시나리오를 제외하고는 충분히 걱정할 필요가 없습니다.