• 关于 Span 的一切:探索新的 .NET 明星:5. .NET 运行时的处理


    .5. NET 运行时会怎么样?

    .NET 运行时提供的安全保证之一是确保访问数组的下标不会越界,实践中被称为边界检查,考虑如下方法:

    [MethodImpl(MethodImplOptions.NoInlining)]
    static int Return4th(int[] data) => data[3];
    

    在我撰写本文的 x64 机器上,生成的汇编代码如下所示:

    sub      rsp, 40
           cmp      dword ptr [rcx+8], 3
           jbe      SHORT G_M22714_IG04
           mov      eax, dword ptr [rcx+28]
           add      rsp, 40
           ret
    G_M22714_IG04:
           call     CORINFO_HELP_RNGCHKFAIL
           int3
    

    cmp 指令比较下标 3 与数组的长度,如果下标 3 越界,随后的 jbe 指令跳转到检查失败代码 ( 抛出异常 )。JIT 需要生成代码来确保此类访问不会导致下标越界,但是这不意味着每次独立的数组访问都需要边界检查。考入下面的 Sum 方法:

    static int Sum(int[] data)
    {
      int sum = 0;
      for (int i = 0; i < data.Length; i++) sum += data[i];
      return sum;
    }
    

    JIT 需要生成确保访问 data[i] 的代码不会下标越界,但是因为可以告诉 JIT,从循环结构 i 永远不会越界 ( 循环从头到尾遍历每个元素 ),JIT 可以优化掉对数组访问的边界检查。这样,生成的汇编代码如下所示:

    G_M33811_IG03:
           movsxd   r9, edx
           add      eax, dword ptr [rcx+4*r9+16]
           inc      edx
           cmp      r8d, edx
           jg       SHORT G_M33811_IG03
    

    cmp 指令还在循环中,但是只是简单地比较下标 i 和数组的长度 ( 它保存在 r8d 寄存器中 ),没有了其它的边界检查。

    运行时使用类似对 Span ( 包括 Span<T> 和 ReadOnlySpan<T> ) 的优化。对比上一示例的如下代码,这里仅仅变更了参数类型:

    static int Sum(Span<int> data)
    {
      int sum = 0;
      for (int i = 0; i < data.Length; i++) sum += data[i];
      return sum;
    }
    

    上述代码生成的汇编代码几乎相同。

    G_M33812_IG03:
           movsxd   r9, r8d
           add      ecx, dword ptr [rax+4*r9]
           inc      r8d
           cmp      r8d, edx
           jl       SHORT G_M33812_IG03
    

    汇编代码非常类似,因为省去了边界检查。但是因为 JIT 识别到 Span 原生的索引器,意味着 JIT 对索引器生成特定的代码,而不是转换实际代码到汇编中。

    所有这些说明了,对于运行时可以使用 Span 对数组相同类型的优化,使得 Span 成为访问数据的高效机制。更深入内容请参见:bit.ly/2zywvyI

  • 相关阅读:
    Vue.js 章6 v-model与表单
    Vue.js 简单购物车开发
    Vue.js实战 章五:内置指令
    Vue stage3
    Vue初接触 stage1
    前端代码的一些恶优化
    websocket介绍 以及 vue websocket使用案例
    回忆一下跨域
    如何使用Flexible这样的一库来完成H5页面的终端适配
    css 输入px单位的数值 直接转换为rem的插件
  • 原文地址:https://www.cnblogs.com/haogj/p/16228246.html
Copyright © 2020-2023  润新知