当前位置: 移动技术网 > IT编程>开发语言>.net > C#效率优化(2)-- 方法内联

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

2019年02月01日  | 移动技术网IT编程  | 我要评论

  一、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
出处:

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

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网