zoukankan      html  css  js  c++  java
  • C# 内联函数

      自从使用C#以来,很少用到内联函数,甚至都没想过,但从事数据采集处理过程中追求处理速度与代码简洁时,内联无疑是一个利器。

      不同于C++的 inline 关键字,在C#中需要使用特性,使用方法如下:

      MethodImpl:实现了Method, Impl,implemented,其指示 CLR 即时编译时的方式。
      MethodImplOptions:是一个枚举类型,但允许按位组合。
        其中 AggressiveInlining 表示,The method should be inlined if possible.(即不保证一定会内联)
    class TestClass
    {
    //运行时才能决定是否执行内联 [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
    public ushort setUInt16(float src, ushort k = 1) {   return (ushort)(src * k); }   //对照 public uint setUInt32(float src, uint k = 10) { return (uint)(src * k); } } class Program { static DateTime StartTime = DateTime.Now; static void Main(string[] args) { TestClass my = new TestClass(); ushort ms = my.setUInt16(10, 2); uint mi = my.setUInt32(10.2f, 2); } }

    C#在开发时编译结果是中间语言,通过 ILDASM 查看,主要代码如下:

    .method public hidebysig instance uint16 setUInt16(float32 src, [opt] uint16 k) cil managed aggressiveinlining
    {
      .param [2] = uint16(0x0001)
      // 代码大小       6 (0x6)
      .maxstack  8
      IL_0000:  ldarg.1
      IL_0001:  ldarg.2
      IL_0002:  conv.r4
      IL_0003:  mul
      IL_0004:  conv.u2
      IL_0005:  ret
    } // end of method TestClass::setUInt16
    
    .method public hidebysig instance uint32  setUInt32(float32 src, [opt] uint32 k) cil managed
    {
      .param [2] = uint32(0x0000000A)
      // 代码大小       7 (0x7)
      .maxstack  8
      IL_0000:  ldarg.1
      IL_0001:  ldarg.2
      IL_0002:  conv.r.un
      IL_0003:  conv.r4
      IL_0004:  mul
      IL_0005:  conv.u4
      IL_0006:  ret
    } // end of method TestClass::setUInt32
    
    .method private hidebysig static void  Main(string[] args) cil managed
    {
      .entrypoint
      // 代码大小       31 (0x1f)
      .maxstack  8
      IL_0000:  newobj     instance void S7SmartDriver.TestClass::.ctor()
      IL_0005:  dup
      IL_0006:  ldc.r4     10.
      IL_000b:  ldc.i4.2
      IL_000c:  callvirt   instance uint16 S7SmartDriver.TestClass::setUInt16(float32,
                                                                              uint16)
      IL_0011:  pop
      IL_0012:  ldc.r4     10.2
      IL_0017:  ldc.i4.2
      IL_0018:  callvirt   instance uint32 S7SmartDriver.TestClass::setUInt32(float32,
                                                                              uint32)
      IL_001d:  pop
      IL_001e:  ret
    } // end of method Program::Main

    在 setInt16 上加的 MethodImplOptions.AggressiveInlining 特性,对应于 IL 中的 aggressiveinlining, 而两者在 Main 调用方式没有区别。

    在运行时CLR会将 IL 代码即时编译, 此时会根据CPU型号进行优化,至于在运行时是否真的进行了内联,那就看CLR的心情啦。

     毕竟 aggressiveinlining 并非C++中的内联,也非宏替换,只是 The method should be inlined if possible.

  • 相关阅读:
    Selenium+Java自动化之如何优雅绕过验证码
    Java替换中使用正则表达式实现中间模糊匹配
    【转】Jmeter中使用CSV Data Set Config参数化不重复数据执行N遍
    【转】安全测试===如何查看浏览器保存的密码
    JMeter 中_time 函数的使用(时间戳、当前时间)
    TCP拆包粘包之分隔符解码器
    TCP粘包/拆包问题
    Netty 入门示例
    JDK AIO编程
    JDK NIO编程
  • 原文地址:https://www.cnblogs.com/ShengunErshu/p/12171212.html
Copyright © 2011-2022 走看看