2

I tried understanding the beforefieldinit flag. I wrote two simple classes

class Foo
{
    public static object o;
    static Foo()
    {
        o = new object();
    }
}

class Bar
{
    public static object o = new object();
}

Then in the Main I used both classes and set a breakpoint to the first line of the Main method - before any code called. In the Watch window I have checked and saw that

  1. Foo.o is null
  2. Bar.o is not null

this is somewhat strange since I thought the purpose of the flag was to be lazy - to prefer not initialize an object until actually needed. This was also written about here

What is the reason for this behavior and does it affect performance ?

I then wanted to check performance, so I wrote the following code in my Main:

Stopwatch sw = new Stopwatch();
sw.Start();

for (int i = 0; i < 2000000000; i++)
{
    object foosObject = Foo.o;
    if (foosObject == null)
    {
        Console.WriteLine("");
    }
}

sw.Stop();
Console.WriteLine("With Static Ctor: " + sw.Elapsed);
sw.Reset();

sw.Start();

for (int i = 0; i < 2000000000; i++)
{
    object barsObject = Bar.o;
    if (barsObject == null)
    {
        Console.WriteLine("");
    }
}

sw.Stop();
Console.WriteLine("Without Static Ctor: " + sw.Elapsed);
sw.Reset();

And the output was

With Static Ctor: 00:00:06.0167153

Without Static Ctor: 00:00:04.2441007

So that's a 50% difference in performance. Why does the first loop run slower ? I have looked at the IL with ILDASM and I didn't see any difference

Community
  • 1
  • 1
Belgi
  • 14,542
  • 22
  • 58
  • 68
  • Looks normal. The JIT executes the cctor in Bar at the time Bar is referenced when compiling Main so that it can assume that Bar is initialized. There's a change request, btw, to make this behavior more controllable: https://github.com/dotnet/roslyn/issues/4448 – usr Sep 18 '15 at 08:29
  • @HansPassant - Why does observing Foo.o didn't invoke it's static constructor while observing Bar.o did initialize it ? – Belgi Sep 18 '15 at 08:42

0 Answers0