2012-03-07 12 views
0

は、誰もが知っているんそして、あなたは理由を説明できますか?オーバーロードされたオペレータの検索のパフォーマンス

+1

この質問はどこから来ますか? 2つのコードは完全に異なっており、私はなぜそれらが比較されているのかわかりません。 –

+0

@Ken:2つのステートメントは同じ入力と同じ出力を持っているため、パフォーマンスを比較するのは理にかなっています。 –

+4

あなたは2頭の馬を持っています。どちらが速いのかを知りたい。だからあなたはインターネット上で見知らぬ人に馬の写真を見せて意見を求めますか?私は馬を競うようになるだろう*。あなたは両方の方法でコードを書いています。今すぐコードを両方の方法で実行する*と*どちらが速いかを確認する*、そしてあなたはあなたの質問に対する答えを知るだろう、見知らぬ人の推測に頼るのではない。 –

答えて

4

最初のバージョンは常に遅くなります。コンパイル時にこのバージョンで非常に簡単に言えることは、実行時に実行されるようになりました。 aとbの型を調べ、それらが+演算子をサポートしているかどうかを調べるなどです。それは多くのものをキャッシュしますが、依然として代理人を呼び出すよりはるかに多くの作業です。

2番目のバージョンでは、これらのチェックはすべてコンパイル時に実行できます。実行時のコストは、デリゲートの作成と呼び出しのみです。例えば

、これらの方法を考えてみましょう。私がやった

private static T Add<T>(T a, T b) 
{ 
    if (Program.<Add>o__SiteContainer0<T>.<>p__Site1 == null) 
    { 
    Program.<Add>o__SiteContainer0<T>.<>p__Site1 = CallSite<Func<CallSite, object, T>>.Create(Binder.Convert(CSharpBinderFlags.None, typeof(T), typeof(Program))); 
    } 
    Func<CallSite, object, T> arg_98_0 = Program.<Add>o__SiteContainer0<T>.<>p__Site1.Target; 
    CallSite arg_98_1 = Program.<Add>o__SiteContainer0<T>.<>p__Site1; 
    if (Program.<Add>o__SiteContainer0<T>.<>p__Site2 == null) 
    { 
    Program.<Add>o__SiteContainer0<T>.<>p__Site2 = CallSite<Func<CallSite, object, object, object>>.Create(Binder.BinaryOperation(CSharpBinderFlags.None, ExpressionType.Add, typeof(Program), new CSharpArgumentInfo[] 
    { 
     CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null), 
     CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null) 
    })); 
    } 
    return arg_98_0(arg_98_1, Program.<Add>o__SiteContainer0<T>.<>p__Site2.Target(Program.<Add>o__SiteContainer0<T>.<>p__Site2, a, b)); 
} 

:対照的に

static T Add<T>(T a, T b) 
{ 
    return ((dynamic)a) + ((dynamic)b); 
} 

static T Add<T>(T a, T b, Func<T, T, T> adder) 
{ 
    return adder(a, b); 
} 

にこれは、コンパイラは最初の方法から生成するものです私のマシンでは、最初のバージョンは2番目のバージョンより約5倍遅いです。私は、違いがより大きくなると予想していたと認めなければなりません。

更新:これがデリゲートよりも遅い理由:生成されたコールサイトコードにもデリゲート(arg_98_0)の呼び出しが含まれる場合、このコード(デリゲート+ Xの呼び出し)は、デリゲートのみを使用するよりも遅くなります。

1

ダイナミックは、初めて実行されるときに強く型付けされた関数よりも遅くなるはずです。そしてなぜ、私はここでStackoverflowのEric Lippertによる決定的な答えを紹介します。

私が理解しているように、反復的なペナルティは、ボクシング、ヒープ上のこれらの値のコピーおよび/または割り当てになります。

C# Dynamic Keyword — Run-time penalty?

関連する問題