• C#测试对比不同类型的方法调用的性能


    一. 测试方法调用形式

    1. 实例方法调用

    2. 静态方法调用

    3. 实例方法反射调用

    4. 委托方法的Invoke调用

    5. 委托方法的DynamicInvoke调用

    6.委托方法的BeginInvoke调用

    二. 测试要点

    1. 首先要先对测试代码和测试工具的方法进行预热处理,即先调用一次然方法通过JIT编译成本机的代码,防止其对时间的损耗(虽然只有一点点,但是还是有影响的);

    2. 关闭电脑上一些运用程序来避免其对我们测试的影响;

    三测试工具代码

    采用老赵写的性能测试工具,见如下地址的文章:

      - 《 一个简单的性能计数器:CodeTimer 》

      - 《 对老赵写的简单性能计数器的修改 》

    我采用的代码来自GitHub:

      - GitHub

    四. 测试代码和测试结果

    代码如下:

    //循环测试次数
    const int iteration = 10000000;
    
    //性能计数器
    CodeTimer codeTimer = new CodeTimer();
    //预热
    codeTimer.Initialize();
    
    //过JIT编译,防止在产生本地代码的时候的时间的消耗
    Test test = new Test();
    test.ShowHelloWorld(null);
    Test.ShowHelloWorldStatic(null);
    
    object obj = new object();
    
    Console.WriteLine("-------------实例方法调用-------------");
    
    CodeTimerResult result = codeTimer.Time(iteration, () =>
        {
            test.ShowHelloWorld(obj);
        });
    Console.WriteLine(result.ToString());
    
    Console.WriteLine("-------------静态方法调用-------------");
    
    result = codeTimer.Time(iteration, () =>
    {
        Test.ShowHelloWorldStatic(obj);
    });
    Console.WriteLine(result.ToString());
    
    Console.WriteLine("-------------反射调用-------------");
    
    result = codeTimer.Time(iteration, () =>
        {
            //调用之前要获得方法
            Type type = typeof(Test);
            MethodInfo methodInfo = type.GetMethod("ShowHelloWorld");
            methodInfo.Invoke(test, new object[] { obj });
        });
    
    Console.WriteLine(result.ToString());
    
    Console.WriteLine("-------------委托调用Invoke-------------");
    
    result = codeTimer.Time(iteration, () =>
    {
        Action<object> action = test.ShowHelloWorld;
        action.Invoke(obj);
    });
    
    Console.WriteLine(result.ToString());
    
    Console.WriteLine("-------------委托调用DynamicInvoke-------------");
    
    result = codeTimer.Time(iteration, () =>
    {
        Action<object> action = test.ShowHelloWorld;
        action.DynamicInvoke(obj);
    });
    
    Console.WriteLine(result.ToString());
    
    Console.WriteLine("-------------异步调用-------------");
    
    result = codeTimer.Time(iteration, () =>
    {
        Action<object> action = test.ShowHelloWorld;
        IAsyncResult ir = action.BeginInvoke(obj, (r) => { }, null);
        action.EndInvoke(ir);
    });
    
    Console.WriteLine(result.ToString());

    运行结果:

     五. 结论

    性能(好-> 差):静态方法调用 > 实例方法调用 > 委托Invoke调用 > 反射调用 > 委托DynamicInvoke调用 > 异步调用

  • 相关阅读:
    mysql分区表批量添加/删除range按天分区(int类型)
    mysql分区表批量添加/删除range按天分区(datetime类型)
    使用obd离线安装oceanbase
    mysqldump导出数据自增属性丢失案例
    Docker启动镜像并设置开机自启
    Docker启动mysql与elasticsearch以及nginx的命令
    Redis学习--从节点过期键清理策略
    Redis学习--渐进式rehash实现原理
    Redis学习--主节点过期键清理策略
    Redis学习--慢日志信息
  • 原文地址:https://www.cnblogs.com/Jeffrey-Chou/p/11912814.html
Copyright © 2020-2023  润新知