2017-02-27 5 views
1

これは最もスマートな質問ではないかもしれませんが、私はそれを回避することはできません。私はメソッドのオーバーロードのパフォーマンスについて疑問を抱いていました。私は今、このクラスのインスタンスを持っているし、(を追加呼び出す場合は、次のように、)メソッドのオーバーロードのパフォーマンス

class testadd 
{ 
    public double _a { get; set; } 
    public double _b { get; set; } 
    public double add(double a, double b) 
    { 
     return a + b; 
    } 
    public double add() 
    { 
     return add(_a, _b); 
    } 
} 

 var tadd = new testadd(); 
     tadd._a = 1; 
     tadd._b = 3; 
     Console.WriteLine(tadd.add()); 

その2回のメソッドの呼び出しを必要としないここで私の質問を説明する簡単な例であります、最初にadd()を追加してから(double a、double b)を追加しますか?より広範なメソッドを使用している場合は、関数本体を再入力する必要がないため、これは非常にきれいですが、パフォーマンスが低下した場合でも、これはまだまだ道のりではありません。コンパイラはこれを理解していますか?これについて心配する必要はありませんか?

+0

ストップウォッチを使用した巨大なループで(印刷ラインなしで)両方を実行しようとしましたか?結果コードを逆コンパイルするには? – AFract

+3

何をパラメータにする必要があるのメンバーを作成しないでください。この質問はオーバーロードとは関係ありません。あなたの 'add()'は 'foo()'と呼ばれることもあります。問題は、コールチェーン内の余分なメソッドがパフォーマンスに大きな影響を与えるかどうかです。たとえそれがあっても、それについて何をするつもりですか? – CodeCaster

+0

申し訳ありませんが、あなたの最初の部分を詳しく説明できますか?私は専門家ではない。私はそれについて何をすることができます、私は単に、両方のメソッドに関数本体をコピーして、1つの呼び出しを保存することができます – nik

答えて

2

最初に注意しなければならないのは、C#がコンパイルするCILがどのメソッドで呼び出すかが非常に明示的であるため、どのバージョンのメソッドを呼び出すべきかを決める際の実行時コストがないということです。

オーバーロードのコストと利点は完全に意味があります。彼らは、(もしうまく利用されていれば)どちらかというとその違いが合理的に推測され、それを裏付けるために文書化された同じ操作の変種として(特にあるものが別のものに対する「デフォルト」の値を持つバリアントである場合)、そうでなければ(悪い場合には)異なるオペレーションに同じ名前が与えられます。

次の注意点は、小さくてシンプルなメソッドはインライン化が期待できるため、tadd.add()を呼び出すコストは(リリースビルドでは)とにかくtadd.add(tadd._a, tadd._b)を呼び出すコストとほぼ同じであることになります。 _a_bprivateであっても、このフォームを直接呼び出すことはできません。つまり、privateは、コンパイラやジッタの処理ではなく、C#コードでできることに制限があります。 taddがフィールドの場合は、3回ではなく1回だけフィールドをロードするという利点もあります。

我々はFoo(int a, int b, int c)cを持っている場合、実際にその中のマイクロ最適化として可能オーバーロードのための一つの理由は、メソッドを呼び出すのサイズを小さくし、その時々であることがそれらをより可能性を高めることができFoo(int a, int b) => Foo(a, b, 0)を追加する通話の大多数のための0です順番にインライン展開されます。それは非常に間違いなくマイクロ最適化ですが、ほとんどの場合、自分のために行う価値はありません。あなたがそれをオーバーロードする時間の99.9%は、コードをより明確にするためであるべきです。 0.1%は実際にホットな道で助けになったかどうかを測定する必要があります。 (私はまだ、オーバーロードのコストと利点は完全に意味があると言っています。なぜなら、これが助けになるのであれば、そのメソッドを何か他のものと呼ぶだけでも助けになるからです。

* "シンプル"は必ずしも単純なものではなく、 "小"は相対的ですが、暗黙的または明示的にラップされない単一の呼び出しを行うものはtryブロックで、仮想ではなく、型は非常にインライン化される可能性があります。

関連する問題