I noticed that the startup time may vary depending on where I placed part of the initialization code. I thought it was really strange, so I wrote a small benchmark that confirmed my suspicions. It seems that the code executed before calling the main method is slower than usual.
Why Benchmark(); works at different speeds depending on whether it is called before and after regular code?
Here is the reference code:
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; } }
The results show that Benchmark() works almost twice as slow for both the static constructor and the constructor for the static Program program property:
// 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
Doubling the number of iterations in the reference loop forces all times to double, assuming that the resulting performance failure is not a constant, but a factor.
// 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
Why is this so? It would be wise if initialization were as fast, if it was done where it belongs. Testing was performed in .NET 4, release mode, optimization enabled.
Zong
source share