2021-12-26

Why the CLR keeps checking static members for type constructor invocation even after the constructor invoked?

I understand that when a type declares an explicit static constructor, the just-in-time (JIT) compiler adds a check to each static method and instance constructor of the type to make sure that the static constructor was previously called.

This behaviour I can imagine it as the following code (correct me please if I’m wrong with this conclusion):

class  ExplicitConstructor
    {
        private static string myVar;

        // Force “precise” initialization 
        static ExplicitConstructor() { myVar = "hello, world";} 
    
        
        /* CLR: if the type constructor didn't invoked 
                then add a call to the type constructor */
        public static string MyProperty
        {
            get { return myVar; }
        }
        
        /* CLR: if the type constructor didn't invoked 
                then add a call to the type constructor */
        public ExplicitConstructor()
        {
            Console.WriteLine("In instance ctor");
        }

    }

    class ImplicitConstructor 
    { 
        private static string myVar = "hello, world";
        
        public static string MyProperty
        {
            /* CLR: Invoke the type constructor only here */
            get { return myVar; }
        }
        
        public ImplicitConstructor()
        {
            Console.WriteLine("In instance ctor");
        }
    }

According to performance rules, this behaive has an impact on the performance because of the checks that the runtime performs in order to run the type initializer at a precise time.

[MemoryDiagnoser]
[Orderer(SummaryOrderPolicy.FastestToSlowest)]
[RankColumn]
public class BenchmarkExample
{
    public const int iteration = Int32.MaxValue - 1;

    [Benchmark]
    public void BenchExplicitConstructor()
    {
        for (int i = 0; i < iteration; i++)
        {
            var temp = ExplicitConstructor.MyProperty;
        }
    }

    [Benchmark]
    public void BenchImplicitConstructor()
    {
        for (int i = 0; i < iteration; i++)
        {
            var temp = ImplicitConstructor.MyProperty;
        }
    }

}
Method Mean Error StdDev Rank Allocated
BenchImplicitConstructor 982.6 ms 56.64 ms 163.4 ms 1 -
BenchExplicitConstructor 7,361.4 ms 318.19 ms 933.2 ms 2 -

Why did the CLR, instead of adding a check to each static method/instance constructor of the type to make sure that the type constructor was previously called, check if the type constructor had been invoked (only once)? 



from Recent Questions - Stack Overflow https://ift.tt/3FiqzJ5
https://ift.tt/eA8V8J

No comments:

Post a Comment