• C#效率优化(2)-- 方法内联


      一、JIT编译器可以通过将方法内联展开(Method Inline Expansion)来提升效率,类似C++中的内联函数(Inline Function),与C++的内联函数不同的是,C#并不支持内联函数,而是由JIT编译器在运行时自动进行;

      1.对于虚方法,如果JIT编译器可以确认调用该方法时变量的运行时类型,支持方法内联;如果不可以确认变量的运行时类型,则不支持方法内联;对于调用空虚方法,与支持方法内联相比,不支持内联用时约长5倍;
    ※包括虚属性、虚索引器、虚事件都不支持方法内联;
    ※抽象方法与虚方法在方法内联方面基本一致;

      2.对于接口方法,如果使用该类型的变量调用,支持方法内联;如果使用接口类型的变量调用,则不支持方法内联;对于调用空接口方法,与使用类型的变量调用,使用接口的变量调用用时长约8倍:

    public class MyBaseClass
    {
        public virtual void MyFunc() { }
    }
    public interface IMyInterface
    {
        void MyFunc();
    }
    public class MyClass : MyBaseClass, IMyInterface
    {
        public override void MyFunc() { }
    }
    //使用时:
    MyClass myClass = new MyClass();
    MyBaseClass myBaseClass = new myBaseClass();
    IMyInterface myInterface = myClass;
    Stopwatch stopwatch = new Stopwatch();
    stopwatch.Start();
    for (int i = 0; i < 1000000000; i++)
    {
        myClass.MyFunc();
    }
    stopwatch.Stop();
    Console.WriteLine(stopwatch.ElapsedMilliseconds); //320
    myBaseClass = myClass; //多次赋值以使JIT编译器无法确认该变量的运行时类型
    stopwatch.Restart();
    for (int i = 0; i < 1000000000; i++)
    {
        myBaseClass.MyFunc();
    }
    Console.WriteLine(stopwatch.ElapsedMilliseconds); //1600
    stopwatch.Restart();
    for (int i = 0; i < 1000000000; i++)
    {
        myInterface.MyFunc();
    }
    Console.WriteLine(stopwatch.ElapsedMilliseconds); //2560

      二、其它不会内联的情况:

      1.递归方法;
      2.包含循环语句的方法;
      3.包含异常处理的方法;
      4.方法体的IL代码长度超过32字节的方法;
    ※可以通过在方法声明中加入命名空间System.Runtime.CompilerServices中的特性MethodImpl来忽略这个条件:

    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public void MyFunc()
    {
        //do…
    }

    如果您觉得阅读本文对您有帮助,请点一下“推荐”按钮,您的认可是我写作的最大动力!

    作者:Minotauros
    出处:https://www.cnblogs.com/minotauros/

    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

  • 相关阅读:
    深度医疗(1)
    ENVI 5.X 影像处理入门实战教程-视频课程
    linux C++通讯架构实战 卷1-视频教程
    2 分钟把握 Envoy 的脉络,适应新场景的 envoy 有哪些不同?能做什么?
    Kubernetes Ingress诡异的502、503、504等奇葩问题(二)
    Kubernetes Ingress诡异的502、503、504等奇葩问题(一)
    Docker容器数据管理(数据卷&数据卷容器)
    SQL Server表水平分区
    从Asp .net到Asp core (第二篇)《Asp Core 的生命周期》
    从Asp .net到Asp core (第一篇)《回顾Asp .net生命周期与管道机制》
  • 原文地址:https://www.cnblogs.com/minotauros/p/10341386.html
Copyright © 2020-2023  润新知