2012-02-27 18 views
7

ビジュアルスタジオにC#メソッドを作成しました。このメソッドは、それぞれのケースで値が返されるswitch文だけを含んでいました。個人的な習慣によって、私は次のコードに似た何かを置く:C#Switch Statement:デフォルトを使用しない方が効率的ですか?

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"; 
     } 
    } 

REVISION: 私がより具体的であることを思わ:コンパイルすると...少ない効率的なコードは、1つまたはその他によって生成されるのですか?

私はパフォーマンスの違いが重要でないかもしれないことを認識しています...私は本当に好奇心です。

+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  "result 4" 
    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  "no result" 
    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が付属しています。これはILのアセンブリコードであり、CPUには見られないものです。 SDK NGen.exeに付属のツールを使用してそのアセンブリを生成することはできますが、ハードウェアによって異なる方法で最適化する可能性があります。 –

4

他のケースが有効でない状況では、スイッチのベースに常にデフォルトのケースを含めることをお勧めします。

前のケースのうちの1つがヒットした場合、プログラムは他のケースをチェックしません(if/else if/elseを使用するのと同じですが、最後のelseがデフォルトです) 。

これが役に立ちます。

+0

のにIFSよりもはるかに高速することができますが、一つは、あなたが同等で何を意味するか服用に注意する必要があります:http://stackoverflow.com/questions/445067/if-vs-switch-speed –

+0

しかし、コンパイルされます...より多くのコードは、どちらか一方によって生成されますか?したがって、予期された条件のいずれも満たされないときに、より多くの命令が実行されることになる。 – bsara

+0

多くのコードが必ずしも効率が悪いとは限りません。 –

3

functionとswitch文の代わりに、キーがKofaxEnvironmentで、スイッチから戻ってきた値と同じ値の汎用辞書を使う方がよいでしょう。ような何か:

Dictionary<KofaxEnvironment, string> 

または

Dictionary<int, string> 

私もパフォーマンスを心配しないでしょう。正しさはあなたの最初の目標でなければなりません。

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

とパフォーマンスのためとして、差(すべてであれば)スイッチのデフォルトの間に通って落ちる:あなたが例外をスローし、デフォルトを使用するスイッチに固執しなければ

しかし、返品はごくわずかです。

+0

これはまさに私が得ているものではありません...しかし、それは素晴らしい考えです...私は将来それを間違いなく使用します。はるかにクリーンなコード! – bsara

関連する問題