2011-08-27 7 views
2

질문 : 변수를 자체에 할당 할 때 중요한 성능이 저하됩니까?변수 자체를 할당 할 수있는 할당 문의 효율성 문제

코드는 쉽게 변수를 할당하거나 플래그를 사용하여 무언가를 지정해야하는 것을 피하기 위해 쉽게 변경할 수 있지만 null 통합 연산자를 사용하여보다 명확한 초기화 코드를 작성하는 것이 좋습니다. 다음 코드를 고려하십시오.

public class MyObject 
    { 
     public string MyString { get; set; } 
    } 

    public class Worker 
    { 
     Dictionary<int, string> m_cache = new Dictionary<string, string>(); 

     public void Assign(ref MyObject obj) 
     { 
     string tmp = null; 
     if (some condition) 
     { 
      //can't pass in MyObject.MyString to out param, so we need to use tmp 
      m_cache.TryGetValue("SomeKey", out tmp); //assumption: key is guaranteed to exist if condition is met 
     }  
     else 
     { 
      obj.MyString = MagicFinder(); //returns the string we are after 
     } 
     //finally, assign MyString property 
     obj.MyString = tmp ?? obj.MyString; 

     //is there a significant performance hit here that is worth changing 
     //it to the following? 

     if (!string.IsEmptyOrNull(tmp)) 
     { 
      obj.MyString = tmp; 
     } 
     } 
    } 
+0

무엇이 질문입니까? – svick

+0

나는 이것이 문제라고 생각한다. (출처를 보라) : "여기에 상당한 성능 저하가 있었는데, 다음과 같이 변경해야 할 가치가 있는가?" – Lucero

+0

사과드립니다. 나는 명확한 하나의 라이너를 만들었어야했는데, Lucero는 정확하다. –

답변

3

귀하의 질문은이 섹션을 졸이다 것 같다 :

//finally, assign MyString property 
obj.MyString = tmp ?? obj.MyString; 

에 :

//is there a significant performance hit here that is worth changing 
//it to the following? 
if (!string.IsNullOrEmpty(tmp)) 
{ 
     obj.MyString = tmp; 
} 

가 실현하지만, 두 가지 버전이 동일하지 것이다. 첫 번째 경우 (널 병합 작업 사용) obj.MyStringstring.Empty에 할당 될 수 있습니다. 두 번째 경우는 string.IsNullOrEmpty을 검사하므로 null이 아닌 빈 문자열 인 경우 할당을 우선 처리하므로 명시 적으로이를 방지합니다.

동작이 다르므로이 동작은 최적화가 아니라 동작 변경이라고합니다. 이 방법이 적절한 지 여부는이 방법이 설명하기 위해 지정된 동작에 따라 다릅니다. 빈 문자열은 어떻게 처리해야합니까? 그것은 여기서 결정적인 요인이되어야합니다.

명시 적 null 체크를 수행하면 퍼포먼스가 거의 동일 할 것입니다. 유지 보수 성과 가독성을 위해 나에게 제안합니다. 첫 번째 버전은 짧고 명확합니다.


또한 코드를 살펴보면 할당 문을 명세서에 넣는 것이 훨씬 간단하다고 생각합니다. 이것은 코드를 훨씬 더 유지 보수 할 수있게합니다. (그리고 더 효율적으로, 당신의 상사의 즐거움에 ...) :

public void Assign(MyObject obj) // No reason to pass by ref... 
    {   
    obj.MyString = someCondition ? m_cache["SomeKey"] : MagicFinder(); 
    } 
0

"시기상조 최적화는 모든 악의 뿌리입니다."

다른 말로하면, 이론적 인 대답이 실제 성능을 나타내는 것이 아닌지 의심 스럽지만, 바이트 코드로 컴파일하는 방법을 알지 못한다면 ... 실행 속도가 빠르며 더러운 테스트 프레임 워크를 만드는 것이 어떻습니까? 무작위 값 (null 또는 유효한 문자열)을 사용하여 1000 번 시도하고 성능을 직접 측정 할 수 있습니까?

EDIT : 퍼포먼스가 크게 다르다면 추가하는 것이 좋을 것입니다. 가독성 우선으로 이동하십시오 (두 가지 모두를 선호한다고 주장 할 수도 있음).

+0

내 상사가 최적화 된 나치이기 때문에 걱정해야합니다. = P –

+0

음, Femaref가 언급했듯이, 관리 코드 컴파일러는 현재 우리 인간보다 더 잘합니다. 이것은 어셈블리 나 C 코드가 아닙니다. 그러나 정말로 중요한 경우 테스트 루프를 만들어 데이터를 신뢰하십시오. –

1

걱정하지 않아도됩니다. 영향은 최소화해야합니다. 그러나 얼마나 많은 사람들이 null 병합 연산자에 대해 실제로 알고 있는지 생각해보십시오. 개인적으로, 나는 한눈에 후자를 더 쉽게 읽을 수 있습니다. 당신이 의미하는 바를 생각할 필요가 없습니다.

+0

내 상사가 최적화 된 나치이기 때문에 항상 걱정해야합니다. = P –

+0

컴파일러와 JIT는 훨씬 뛰어나다. 그러나 나는 당신에게 말할 필요가 없다고 생각한다. – Femaref

1

의 성능 걱정 :

public void Assign(ref MyObject obj) 
    {   
    if (some condition) 
    { 
     string tmp = null; 
     //can't pass in MyObject.MyString to out param, so we need to use tmp 
     m_cache.TryGetValue("SomeKey", out tmp); //assumption: key is guaranteed to exist if condition is met 
     obj.MyString = tmp; 
    }  
    else 
    { 
     obj.MyString = MagicFinder(); //returns the string we are after 
    } 
    } 

코드의 가정 (당신의 조건에 해당하는 경우 키가 항상 캐시에 존재하는 것)을 감안할 때, 당신도이를 단순화 할 수 있습니다 문자열이 null이거나 비어 있는지 확인하는 것이 즉각적인 문제는 아니지만 코드를 간결하게 변경할 수 있다고 생각합니다. 내 생각에 :

string tmp = null; 
if (some condition) 
{ 
    m_cache.TryGetValue("SomeKey", out tmp); 
}  
if (string.IsNullOrEmpty(tmp)) 
{ 
    tmp = MagicFinder(); 
}  
obj.MyString = tmp;