ここでは起動時間が異なることに気付きました。初期化コードを配置しました。私はこれが本当に奇妙だと思ったので、小さなベンチマークを書いて、私の疑惑を確認しました。メインメソッドが呼び出される前に実行されるコードは、通常よりも遅いようです。静的コンストラクタのコードが遅く実行される
通常のコードパスの前後で呼び出されるかによって、Benchmark();
が異なる速度で動作するのはなぜですか?
ここではベンチマークのコードです:
class Program {
static Stopwatch stopwatch = new Stopwatch();
static Program program = new Program();
static void Main() {
Console.WriteLine("main method:");
Benchmark();
Console.WriteLine();
new Program();
}
static Program() {
Console.WriteLine("static constructor:");
Benchmark();
Console.WriteLine();
}
public Program() {
Console.WriteLine("public constructor:");
Benchmark();
Console.WriteLine();
}
static void Benchmark() {
for (int t = 0; t < 5; t++) {
stopwatch.Reset();
stopwatch.Start();
for (int i = 0; i < 1000000; i++)
IsPrime(2 * i + 1);
stopwatch.Stop();
Console.WriteLine(stopwatch.ElapsedMilliseconds + " ms");
}
}
static Boolean IsPrime(int x) {
if ((x & 1) == 0)
return x == 2;
if (x < 2)
return false;
for (int i = 3, s = (int)Math.Sqrt(x); i <= s; i += 2)
if (x % i == 0)
return false;
return true;
}
}
結果はBenchmark()
がstatic Program program
プロパティの静的コンストラクタと、コンストラクタの両方のためにほぼ倍の実行速度が遅いことを示しています
// static Program program = new Program()
public constructor:
894 ms
895 ms
887 ms
884 ms
883 ms
static constructor:
880 ms
872 ms
876 ms
876 ms
872 ms
main method:
426 ms
428 ms
426 ms
426 ms
426 ms
// new Program() in Main()
public constructor:
426 ms
427 ms
426 ms
426 ms
426 ms
は、ベンチマーク・ループはすべての時間を倍にし、発生するパフォーマンス・ペナルティが一定ではなく、要因であることを示唆しています。
// static Program program = new Program()
public constructor:
2039 ms
2024 ms
2020 ms
2019 ms
2013 ms
static constructor:
2019 ms
2028 ms
2019 ms
2021 ms
2020 ms
main method:
1120 ms
1120 ms
1119 ms
1120 ms
1120 ms
// new Program() in Main()
public constructor:
1120 ms
1128 ms
1124 ms
1120 ms
1122 ms
これはどうしてですか?初期化がそれが所属する場所で完了した場合と同じ速さであれば意味があります。テストは.NET 4で、リリースモードで、最適化を行った。
正確な質問は何ですか? – jcolebrand
設定をコンパイルしますか?フレームワークのバージョン? – user7116
私の編集が意味を持つかどうか確認してください(私には分かりません).Net 4/releaseで同様の結果を試しました。 –