• 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.

  • 相关阅读:
    第二章 Google guava cache源码解析1--构建缓存器
    第十一章 AtomicInteger源码解析
    JVM虚拟机(五):JDK8内存模型—消失的PermGen
    JVM虚拟机(四):JVM 垃圾回收机制概念及其算法
    Java中RunTime类介绍
    JVM虚拟机(三):参数配置
    ZooKeeperEclipse 插件
    zookeeper(五):Zookeeper中的Access Control(ACL)
    zookeeper(六):Zookeeper客户端Curator的API使用详解
    Java并发编程(九):拓展
  • 原文地址:https://www.cnblogs.com/ShengunErshu/p/12171212.html
Copyright © 2020-2023  润新知