2012-02-26 16 views
-1

私は2つの単純なアプリケーションを書いた: 1. 1つは匿名メソッドを使用し、もう1つは 2.簡単なメソッドを使用する。私のテストで匿名メソッドが高速になるのはなぜですか?

上記の各方法は、単純なアクションをやっている:

int add(int n1, int n2) {return n1+n2} 

をそして私はaddメソッド万回を呼び出します簡単なforループを呼び出します。匿名メソッドを使用する実装は、他のメソッドよりもはるかに時間がかかります。どうして?それはJITterが匿名メソッドをインライン化するからですか?

delegate int ADD(int i1, int i2); 

private void button1_Click(object sender, EventArgs e) 
    { 
     Stopwatch watch = new Stopwatch(); 
     watch.Reset(); 

     watch.Start(); 

     for(int i = 0 ; i < 10000 ; i++) 
     { 
      add(i, i); 
     } 

     watch.Stop(); 
     Console.WriteLine("Normal Call " + watch.ElapsedTicks); 

     watch.Reset(); 
     watch.Start(); 
     for(int i = 0 ; i < 10000 ; i++) 
     { 
      ADD p = delegate(int n1, int n2) 
      { 
       return n1 + n2; 
      }; 

      p.Invoke(i, i); 
     } 

     watch.Stop(); 
     Console.WriteLine(watch.ElapsedTicks); 

     Console.ReadLine(); 


    } 

    int add(int n1, int n2) 
    { 
     return n1 + n2; 
    } 
} 

結果 - リリースモードに - (回のアクションボタンのカップルに押された)のx64でコンパイル:

Normal 1525 
1275 
Normal 480 
477 
Normal 371 
370 
Normal 372 
371 
Normal 477 
479 
Normal 477 
477 
Normal 564 
702 
Normal 478 
476 
+5

1000回だけ?現代のコンピュータであれば1ミリ秒未満で実行できます。一方、お使いのコンピュータの時計は、その間隔を小さく測定するのが苦労しています。あなたのタイミングコードを投稿してください。 –

+0

この質問に答えるのに十分な情報はここにはありません。 1つのリリースまたはデバッグモードになっていますか? – asawyer

+0

私はStopwatchをコンソールに使用しました。ループを実行するのにかかる時間は、リリースとデバッグでは '匿名メソッド'を使用していましたが、その後は通常のメソッドでした。 – Yanshof

答えて

2

私はあなたの結果を確認することができませんでした。

私のテストでは、「通常」の機能は、委任先よりもはるかに優れた性能を発揮します。

class Program { 

    delegate int ADD(int i1, int i2); 

    static int add(int n1, int n2) { 
     return n1 + n2; 
    } 

    static void Main(string[] args) { 

     Stopwatch watch = new Stopwatch(); 

     watch.Start(); 

     const int count = 100000; 

     for (int i = 0; i < count; i++) { 
      add(i, i); 
     } 

     watch.Stop(); 
     Console.WriteLine(watch.ElapsedTicks); 

     ADD p = delegate(int n1, int n2) { 
      return n1 + n2; 
     }; 

     watch.Reset(); 
     watch.Start(); 
     for (int i = 0; i < count; i++) { 
      p.Invoke(i, i); 
     } 

     watch.Stop(); 
     Console.WriteLine(watch.ElapsedTicks); 

    } 

} 

この版画:あなたは結果をスキュー何かをしなければなりません

103 
1321 

ここで私がテストに使用されるあなたの少し変更したコードです。

--- EDIT ---

OK私は、テストの別のラウンド、WinFormsのアプリケーションで、この時間をやりました。

  • WinFormsアプリケーションを「x86」としてコンパイルすると、結果は上記のコンソールアプリケーションと同じになります(関数はデリゲートよりも高速です)。
  • WinFormsを 'x64'としてコンパイルすると、関数は大体、デリゲートのレベルまで劇的に減速します。
  • 機能がstaticになると、( 'x64' WinFormsビルドで)再びスピードアップします。
  • 上記のコンソールアプリケーションは、 'x64'ビルドであっても、機能が非静的になっているときでさえ、決して減速しません。

すべては、リリース構成でデバッガーの外で測定されました。

+0

私は彼が結果を歪めているとは思わない。私は彼が間違ってそれを読んでいると思うし、トップラインがデリゲートのための結果であり、メソッドの最終行であると思っています。 – Gabe

+0

@Gabeあなたはそれについて正しいかもしれません;) –

+0

いいえ - 私のコードを修正してください - そしてもう一度それを実行しようとしてください! 「通常の」コードは遅く実行されます。 – Yanshof

関連する問題