2012-02-27 2 views
7

Visual Studio에서 각 사례에서 값을 반환하는 switch 문만 포함 된 C# 메서드를 만들었습니다. 개인 습관, 나는 다음과 같은 코드와 유사 뭔가를 넣어 :C# Switch 문 : 기본값을 사용하지 않는 것이 더 효율적입니까?

private string SwitchMethod(int num) 
    { 
     switch (num) 
     { 
      case 0: 
       return "result 1"; 
      case 1: 
       return "result 2"; 
      case 2: 
       return "result 3"; 
     } 
     return "no result"; 
    } 

내 질문은 이것이다 : 더 나은 성능을해야합니다 어떤 코드? 위 또는 아래의 코드 또는 동일합니까? 그리고 왜?

나는 컴파일러 최적화로 인해 ... 그들은 단지 같을 수도 있다고 생각 하겠지만, 나는 정말로 모른다.

private string SwitchMethod(int num) 
    { 
     switch (num) 
     { 
      case 0: 
       return "result 1"; 
      case 1: 
       return "result 2"; 
      case 2: 
       return "result 3"; 
      default: 
       return "no result"; 
     } 
    } 

개정 : 좀 더 구체적으로해야한다는 것 : 컴파일하면 ... 덜 효율적인 코드가 하나 또는 다른에 의해 생성됩니다?

나는 성능의 차이가 중요하지 않을 수 있다는 것을 알고있다. 나는 정말로 호기심이 많다.

+4

이것은 꽤 주관적입니다. 메서드 나 함수에서 여러 종료 점을 제외하고 YMMV를 사용합니다. 정말 궁금하다면 IL을보십시오. –

+1

그게 컴파일 된거야? 나는 내 컴파일러 앞에 있지는 않지만, 거의 확실하게 기본값이 필요하다. –

+0

정말로 "일어나지 말아야한다"는 예외를 던지십시오. 실제로는 발생하지 않을 것이라고 생각한다면 – Matt

답변

9
public static string foo(int num) 
     { 
      switch (num) 
      { 
       case 0: 
        return "result 1"; 
       case 1: 
        return "result 2"; 
       case 2: 
        return "result 3"; 
      } 
      return "no result"; 
     } 

가된다 :

.method public hidebysig static string foo(int32 num) cil managed 
{ 
    // Code size  57 (0x39) 
    .maxstack 1 
    .locals init ([0] string CS$1$0000, 
      [1] int32 CS$4$0001) 
    IL_0000: nop 
    IL_0001: ldarg.0 
    IL_0002: stloc.1 
    IL_0003: ldloc.1 
    IL_0004: switch  ( 
         IL_0017, 
         IL_001f, 
         IL_0027) 
    IL_0015: br.s  IL_002f 
    IL_0017: ldstr  "result 1" 
    IL_001c: stloc.0 
    IL_001d: br.s  IL_0037 
    IL_001f: ldstr  "result 2" 
    IL_0024: stloc.0 
    IL_0025: br.s  IL_0037 
    IL_0027: ldstr  "result 3" 
    IL_002c: stloc.0 
    IL_002d: br.s  IL_0037 
    IL_002f: ldstr  "no result" 
    IL_0034: stloc.0 
    IL_0035: br.s  IL_0037 
    IL_0037: ldloc.0 
    IL_0038: ret 
} // end of method Program::foo 

는 기본 케이스에 반환을 이동 :

.method public hidebysig static string foo(int32 num) cil managed 
{ 
    // Code size  57 (0x39) 
    .maxstack 1 
    .locals init ([0] string CS$1$0000, 
      [1] int32 CS$4$0001) 
    IL_0000: nop 
    IL_0001: ldarg.0 
    IL_0002: stloc.1 
    IL_0003: ldloc.1 
    IL_0004: switch  ( 
         IL_0017, 
         IL_001f, 
         IL_0027) 
    IL_0015: br.s  IL_002f 
    IL_0017: ldstr  "result 1" 
    IL_001c: stloc.0 
    IL_001d: br.s  IL_0037 
    IL_001f: ldstr  "result 2" 
    IL_0024: stloc.0 
    IL_0025: br.s  IL_0037 
    IL_0027: ldstr  "result 3" 
    IL_002c: stloc.0 
    IL_002d: br.s  IL_0037 
    IL_002f: ldstr  "result 4" 
    IL_0034: stloc.0 
    IL_0035: br.s  IL_0037 
    IL_0037: ldloc.0 
    IL_0038: ret 
} // end of method Program::foo 

을 정확히 같은. 성능 차이는 없습니다. 코드가 재생성되었는지 확인하기 위해 "결과 없음"을 결과 4로 변경했습니다. 분명히 C# 컴파일러가이를 최적화하거나 아니면 그냥 동등한 것으로 끝납니다.

+0

정말 고마워요! 내 무지를 용서하십시오 ...하지만 어셈블리를 생성하기 위해 당신은 무엇을 사용 했습니까? – bsara

+2

@Brandon 많이 있습니다. 예를 들어 ilspy –

+2

* ILDasm *은 .NET Framework SDK와 함께 제공됩니다. 이것이 CPU가 보는 것과 다른 일리노이 어셈블리 코드입니다. SDK NGen.exe와 함께 제공되는 도구를 사용하여 해당 어셈블리를 생성 할 수 있지만 하드웨어에 따라 다르게 최적화 할 수 있습니다. –

4

다른 사례가 유효하지 않은 경우 스위치의 기본에 항상 기본 사례를 포함시키는 것이 좋습니다.

이전 사례 중 하나에 해당되면 프로그램이 다른 사례를 확인하지 않기 때문에 효율성 문제는 아닙니다 (최종 else가 기본값 인 if/else if/else 사용과 동일합니다) .

희망이 도움이됩니다.

+0

답변은 정상이지만, 동일한 의미의 것을 사용하는 데주의해야합니다. http://stackoverflow.com/questions/445067/if-vs-switch-speed –

+0

하지만 언제 컴파일 된 ... 더 많은 코드가 하나 또는 다른 코드에 의해 생성됩니까? 따라서 예상 조건 중 어느 것도 충족되지 않으면 더 많은 명령이 실행됩니다. – bsara

+0

코드가 많을수록 효율성이 떨어지는 것은 아닙니다. –

3

함수 및 switch 문 대신 키가 KofaxEnvironment이고 스위치에서 반환하는 값과 동일한 일반 사전을 사용하는 것이 좋습니다. 같은 뭔가 :

Dictionary<KofaxEnvironment, string> 

또는

Dictionary<int, string> 

나는 또한 성능에 대해 걱정하지 않을 것입니다. 정확함이 첫 번째 목표 여야합니다.

, 당신은 예외가 발생합니다 기본 사용 스위치를 고수 경우 :

default: 
    throw new ArgumentException("Serious programmer error!"); 

을 그리고 성능 등, 스위치의 기본과까지 떨어지는 사이의 차이 (있는 모든 경우) 반환은 무시할 수있을 것이다.

+0

그건 정확히 내가 뭘 얻었는지 ...하지만 좋은 생각이야 ... 나는 확실히 그것을 미래에 사용합니다. 훨씬 깔끔한 코드! – bsara