7

2つのコードを比較してみましょう。

String str = null;
//Possibly do something...
str = "Test";
Console.WriteLine(str);

String str;
//Possibly do something...
str = "Test";
Console.WriteLine(str);

私はいつも、これらのコードは同じだと思っていました。しかし、これらのコードをビルドし(最適化をチェックしたリリースモード)、生成されたILメソッドを比較した後、最初のサンプルにはさらに2つのIL命令があることに気付きました。

最初のサンプルコードIL:

.maxstack 1
.locals init([0] string str)
IL_0000:ldnull
IL_0001:stloc.0
IL_0002:ldstr "Test"
IL_0007:stloc.0
IL_0008:ldloc.0
IL_0009:call void [mscorlib] System.Console :: WriteLine (文字列)
IL_000e:ret

2番目のサンプルコードIL:

.maxstack 1
.locals init([0] string str)
IL_0000:ldstr "Test"
IL_0005:stloc.0
IL_0006:ldloc.0
IL_0007:call void [mscorlib] System.Console :: WriteLine(string)
IL_000c:ret

おそらく、このコードはJITコンパイラによって最適化されていますか?では、nullを使用したローカルbethod変数の初期化は、パフォーマンスに影響を与えますか(非常に単純な操作であることは理解していますが、どのような場合でも)、回避する必要がありますか?よろしくお願いします。

4

3 に答える 3

8

http://www.codinghorror.com/blog/2005/07/for-best-results-dont-initialize-variables.html

記事から要約すると、さまざまなベンチマークを実行した後、オブジェクトを値に初期化する(定義の一部として、クラスのコンストラクターで、または初期化メソッドの一部として)と、約10〜35%遅くなる可能性があります。 .NET1.1および2.0。新しいコンパイラは、定義の初期化を最適化する可能性があります。原則として初期化を避けることを推奨して記事を締めくくります。

于 2011-01-20T20:55:25.810 に答える
6

Jon.Stromer.Galleyのリンクが指摘しているように、少し遅くなります。しかし、その違いは驚くほど小さいです。おそらくナノ秒のオーダーです。そのレベルでは、C#のような高級言語を使用することによるオーバーヘッドは、パフォーマンスの違いを小さくします。パフォーマンスがそれほど問題になる場合は、CまたはASMなどでコーディングしている可能性があります。

明確なコードを書くことの価値(それがあなたにとって意味するものは何でも)は、コスト対利益の点で0.00001msのパフォーマンスの向上をはるかに上回ります。そもそもC#やその他の高級言語が存在するのはそのためです。

これはおそらく学術的な質問であり、CLRの内部を理解することの価値を軽視していません。しかし、この場合、焦点を合わせるのは間違っているように思われます。

于 2011-01-20T21:21:42.543 に答える
2

今日(2019年)、.NETFrameworkと.NETCoreコンパイラはどちらも、不要な初期化を最適化するのに十分なほどスマートですstloc.0(役に立たない-ldloc.0ペアと一緒に。)

どちらのバージョンも次のようにコンパイルされます

        .maxstack 8

        ldstr "Test"
        call void [System.Console]System.Console::WriteLine(string)
        ret

参考として私のSharpLab実験を参照してください。

もちろん実装は変わりますが、ジャスティンの答えは時代を超えています。私は好奇心からこの実験を行いました。実際の状況では、コードの明確さと表現力に焦点を当て、マイクロ最適化を無視します。

于 2019-07-12T15:17:30.687 に答える