Perf penalty Static Constructor


There was a thread recently over the CLR perf alias that I thought I’d share.


 


One of the WinFX developers asks if there is any perf differences between these two classes:


public class Foo1 {


   public static int Value = 42;


 


}


 


public class Foo2 {


   static Foo2 () {


      Value = 42;


   }


   public static int Value;


 


}


 


The two classes do essentially the same thing: initialize “Value” to 42 before anyone can access it.  But Foo1 is the more preferred way.  Why, because explicit static constructors are expensive because they require that the runtime to insure that the value is set exactly before any member of the class is accessed.    The exact cost is depends on the scenario, but it can be quite noticeable in some cases.


 


But why is Foo1 better?  After all, when we look at the IL, we find out that they BOTH have static constructors that look identical.  In the case of Foo1, the C# compiler added for you.


 


 


            //Foo1 static constructor


.method private hidebysig specialname rtspecialname static


        void  .cctor() cil managed


{


  // Code size       8 (0x8)


  .maxstack  1


  IL_0000:  ldc.i4.s   42


  IL_0002:  stsfld     int32 Foo1::Value


  IL_0007:  ret


} // end of method Foo1::.cctor


 


//Foo2 static constructor


.method private hidebysig specialname rtspecialname static


        void  .cctor() cil managed


{


  // Code size       8 (0x8)


  .maxstack  1


  IL_0000:  ldc.i4.s   42


  IL_0002:  stsfld     int32 Foo2::Value


  IL_0007:  ret


} // end of method Foo2::.cctor


  


 


The secret?  Yet another little metadata mark that the C# compiler emits for in the Foo1 case called beforeFieldInit.


.class public auto ansi beforefieldinit Foo1


This bit tells the runtime it can be a little bit lazy and only run the static constructor when a static member is accessed, not anytime a member of the class is accessed.  As we all know as developers being lazy is faster!   


 


So what?  Avoid using explicit static constructors if you can avoid it (perf Foo1 style code to Foo2 style code).


 


Some good info on the web on this topic… Our perf team pointed to this nice article: http://www.ondotnet.com/pub/a/dotnet/2003/07/07/staticxtor.html 


And I found this site has very useful quotes from the CLI Spec:


http://www.yoda.arachsys.com/csharp/beforefieldinit.html

Comments (15)

  1. Seems like a possible compiler optimization as well since it blits the same IL, it should be able to identify this and blit the field marking.

  2. Kevin Westhead says:

    Wouldn’t it be better to allow explicit declaration of beforefieldinit? E.g.

    [BeforeFieldInit()]

    public class Foo1

    { … }

    This way I could get the advantages of beforefieldinit and still explicitly initialise my static members in the static ctor. In otherwords, it seems logical to expect intialisation to occur in a ctor, with additional behaviours produced via attributes. I would find this preferable to writing the following:

    public class Foo1

    {

    static int s_first = InitializeStaticMembers();

    static int InitializeStaticMembers()

    {

    s_second = 2;

    s_third = 3;

    // etc. for all other static members.

    return 1;

    }

    }

  3. The Microsoft Patterns and Practices Group had a drop of the Web Client Software Factory , so I thought

  4. Nick's Blog says:

    To those who work with me, it may seem odd to see me to put up an entry implying that I’ve written "my first WPF" in recent days. But before this, my work with WPF has been very over-the-shoulder observer and any commentary (and guidance sometimes) has