Performance of Object.GetType()

前端 未结 7 1824
花落未央
花落未央 2020-12-05 03:44

We have lots of logging calls in our app. Our logger takes a System.Type parameter so it can show which component created the call. Sometimes, when we can be bothered, we

7条回答
  •  日久生厌
    2020-12-05 04:20

    I get very different results.
    For this I created a new console app in another project, and used a class with inheritance.

    I created an empty loop to withdraw from the results, for a clean comparison.
    I created a const and a static for the cycles (manually switching which to use).
    Something very interesting happend.

    When using the const, the empty loop become slow, but the buffered var test becomes slightly faster.
    A change that should affect none or all tests, only affect 2.

    Cycles for each test : 100000000

    Using static cycle:

    Object.GetType : 1316
    TypeOf(Class)  : 1589
    Type var       : 987
    Empty Loop     : 799
    
    Clean overview:
    Object.GetType : 517
    TypeOf(Class)  : 790
    Type var       : 188
    

    Using const cycle:

    Object.GetType : 1316
    TypeOf(Class)  : 1583
    Type var       : 853
    Empty Loop     : 1061
    
    Clean overview:
    Object.GetType : 255
    TypeOf(Class)  : 522
    Type var       : -208
    

    I ran these multiple times, and with some small changes, and with 10 times more cycles, to reduce the risk of background processes affecting results. Almost same results as these 2 above.

    It does seem that Object.GetType() is 1.5-2 times as fast as typeof(class).
    The buffered var seem to be 1.5-2 times as fast as Object.GetType().

    I the right application, this is not just micro-optimising.
    If you sacrifice small things here and there, they will easily slow more than the one big thing you made 30% faster.

    Again as JaredPar answered, these kind of tests, is unreliable for telling about your specific application, as we have proven here.
    All our tests giving quite different results, and things seemingly unrelated to the code at hand, can affect the performance.

    The test:

    .NetCore 2.1
    namespace ConsoleApp1
    {
        class Program
        {
            public const int Cycles = 100000000;
            public static int Cycles2 = 100000000;
            public static QSData TestObject = new QSData();
            public static Type TestObjectType;
    
            static void Main(string[] args)
            {
                TestObjectType = TestObject.GetType();
                Console.WriteLine("Repeated cycles for each test : " + Cycles.ToString());
    
                var test1 = TestGetType();
                Console.WriteLine("Object.GetType : " + test1.ToString());
                var test2 = TestTypeOf();
                Console.WriteLine("TypeOf(Class)  : " + test2.ToString());
                var test3 = TestVar();
                Console.WriteLine("Type var       : " + test3.ToString());
                var test4 = TestEmptyLoop();
                Console.WriteLine("Empty Loop     : " + test4.ToString());
    
                Console.WriteLine("\r\nClean overview:");
                Console.WriteLine("Object.GetType : " + (test1 - test4).ToString());
                Console.WriteLine("TypeOf(Class)  : " + (test2 - test4).ToString());
                Console.WriteLine("Type var       : " + (test3 - test4).ToString());
    
                Console.WriteLine("\n\rPush a button to exit");
                String input = Console.ReadLine();
            }
    
            static long TestGetType()
            {
                var stopwatch = new Stopwatch();
                stopwatch.Start();
                for (int i = 0; i < Cycles; i++)
                {
                    Type aType = TestObject.GetType();
                }
                stopwatch.Stop();
                return stopwatch.ElapsedMilliseconds;
            }
    
            static long TestTypeOf()
            {
                var stopwatch = new Stopwatch();
                stopwatch.Start();
                for (int i = 0; i < Cycles; i++)
                {
                    Type aType = typeof(QSData);
                }
                stopwatch.Stop();
                return stopwatch.ElapsedMilliseconds;
            }
    
            static long TestVar()
            {
                var stopwatch = new Stopwatch();
                stopwatch.Start();
                for (int i = 0; i < Cycles; i++)
                {
                    Type aType = TestObjectType;
                }
                stopwatch.Stop();
                return stopwatch.ElapsedMilliseconds;
            }
    
            static long TestEmptyLoop()
            {
                var stopwatch = new Stopwatch();
                stopwatch.Start();
                for (int i = 0; i < Cycles; i++)
                {
                    Type aType;
                }
                stopwatch.Stop();
                return stopwatch.ElapsedMilliseconds;
            }
        }
    }
    

提交回复
热议问题