[c#] usage and efficiency comparison of reflection

Time:2021-8-9

Reflection instantiation class

public class Person
{
    public string Name { get; set; }

    public Person(string name)
    {
        this.Name = name;
    }

    public string Say(string msg)
    {
        return $"{Name}: {msg}";
    }
}

class Program
{
    //Number of tests
    const int count = 10000000;

    static void Main(string[] args)
    {
        CreateInstance0();
        CreateInstance1();
        CreateInstance2();
        CreateInstance3();
        CreateInstance4();

        Console.Read();
    }

    static void CreateInstance0()
    {
        Stopwatch watch = new Stopwatch();
        watch.Start();

        for (var i = 0; i < count; i++)
        {
            Person person = new person ("Zhang San");
        }

        watch.Stop();
        Console.WriteLine($"{watch.Elapsed} - new");
    }

    static void CreateInstance1()
    {
        Stopwatch watch = new Stopwatch();
        watch.Start();

        for (var i = 0; i < count; i++)
        {
            Object person = activator. Createinstance (typeof (person), "Zhang San");
        }

        watch.Stop();
        Console.WriteLine($"{watch.Elapsed} - Activator.CreateInstance");
    }

    static void CreateInstance2()
    {
        Assembly assembly = Assembly.GetExecutingAssembly();

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

        for (var i = 0; i < count; i++)
        {
            Person obj = (person) assembly. Createinstance ("consoletest. Person", true, bindingflags. Default, null, new object [] {Zhang San "}, null, null);
        }

        watch.Stop();
        Console.WriteLine($"{watch.Elapsed} - Assembly.CreateInstance");
    }

    static void CreateInstance3()
    {
        Assembly assembly = Assembly.GetExecutingAssembly();

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

        for (var i = 0; i < count; i++)
        {
            Type type = assembly.GetType("ConsoleTest.Person");
            Object person = activator.createinstance (type, "Zhang San");
        }
        watch.Stop();
        Console.WriteLine($"{watch.Elapsed} - Assembly.CreateInstance1");
    }

    static void CreateInstance4()
    {
        Assembly assembly = Assembly.GetExecutingAssembly();

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

        Type type = assembly.GetType("ConsoleTest.Person");
        for (var i = 0; i < count; i++)
        {
            Object person = activator.createinstance (type, "Zhang San");
        }
        watch.Stop();
        Console.WriteLine($"{watch.Elapsed} - Assembly.CreateInstance2");
    }
}

  • Instantiating an object through reflection is about 50 times slower than direct new
  • assembly.CreateInstanceThanActivator.CreateInstanceSlow, the main performance loss isAssembly.GetType

Reflection calls the method of the class

class Program
{
    //Number of tests
    const int count = 10000000;

    static void Main(string[] args)
    {
        InvokeMethod0();
        InvokeMethod1();
        InvokeMethod2();
        InvokeMethod3();
        InvokeMethod4();

        Console.Read();
    }

    static void InvokeMethod0()
    {
        Person person = new person ("Zhang San");

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

        for (var i = 0; i < count; i++)
        {
            string name = person.Say("Hello World!");
        }

        watch.Stop();
        Console. Writeline ($"{watch. Elapsed} - direct call");
    }

    static void InvokeMethod1()
    {
        Person person = (person) activator. Createinstance (typeof (person), "Zhang San");

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

        for (var i = 0; i < count; i++)
        {
            string name = person.Say("Hello World!");
        }

        watch.Stop();
        Console. Writeline ($"{watch. Elapsed} - Reflection cache class call");
    }

    static void InvokeMethod2()
    {
        Person person = (person) activator. Createinstance (typeof (person), "Zhang San");
        MethodInfo method = typeof(Person).GetMethod(nameof(Person.Say), new Type[] { typeof(string) });
        Func func = (Func)method.CreateDelegate(typeof(Func), person);

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

        for (var i = 0; i < count; i++)
        {
            string result = func("Hello World!");
        }

        watch.Stop();
        Console. Writeline ($"{watch. Elapsed} - delegate call created using reflection");
    }

    static void InvokeMethod3()
    {
        Person person = (person) activator. Createinstance (typeof (person), "Zhang San");

        MethodInfo method = typeof(Person).GetMethod(nameof(Person.Say), new Type[] { typeof(string) });

        object[] parameters = new object[] { "Hello World!" };

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

        for (var i = 0; i < count; i++)
        {
            string name = (string)method.Invoke(person, parameters);
        }

        watch.Stop();
        Console. Writeline ($"{watch. Elapsed} - Method cache call using reflection");
    }

    static void InvokeMethod4()
    {
        Person person = (person) activator. Createinstance (typeof (person), "Zhang San");

        object[] parameters = new object[] { "Hello World!" };

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

        for (var i = 0; i < count; i++)
        {
            string result = (string)(typeof(Person).GetMethod(nameof(Person.Say))?.Invoke(person, parameters));
        }

        watch.Stop();
        Console.writeline ($"{watch. Elapsed} - directly use reflection call");
    }
}

  • After the reflection is obtained, the calling method is the same as the direct calling method.
  • Caching reflection method calls and using reflection calls directly are very inefficient

Recommended Today

Java Engineer Interview Questions

The content covers: Java, mybatis, zookeeper, Dubbo, elasticsearch, memcached, redis, mysql, spring, spring boot, springcloud, rabbitmq, Kafka, Linux, etcMybatis interview questions1. What is mybatis?1. Mybatis is a semi ORM (object relational mapping) framework. It encapsulates JDBC internally. During development, you only need to pay attention to the SQL statement itself, and you don’t need to […]