福冈咸鱼 发表于 2023-11-7 13:29:59

编写高性能C#代码 —— Span<T>

Span 提供任意内存的连续区域的类型安全和内存安全表示形式。它是在堆栈而不是托管堆上分配的ref结构,是对任意内存块的抽象 。
1.关于Span


[*]在NET Core 2.1中首次引入
[*]提供对任意内存上的连续区域的读写视图
[*]利用索引/迭代来修改范围内的内存
[*]几乎无开销
2.和内存的关系

   Span 表示任意内存的连续区域。 Span实例通常用于保存数组的元素或数组的一部分。 但是,与数组不同, Span实例可以指向堆栈上托管的内存、本机内存或托管的内存。
3.性能测试

  Span通常用来处理数组,所以本次测试的场景是数组的切分:从一个数组的中间元素开始,获取并返回四分之一个元素。
  3.1 数组初始化
  这里我们准备一个数组分三种不同长度进行初始化,有利于覆盖到更多的测试情况。
https://img2023.cnblogs.com/blog/2281532/202311/2281532-20231107123059317-817194344.png
 
  3.2 测试采用三种方式,用BenchmarkDotNet比较一下:
  第一种(常规):
https://img2023.cnblogs.com/blog/2281532/202311/2281532-20231107110950664-237198300.png
   第二种(复制):
https://img2023.cnblogs.com/blog/2281532/202311/2281532-20231107111007138-430169467.png
   第三种(Span切片):
https://img2023.cnblogs.com/blog/2281532/202311/2281532-20231107111137019-1512506371.png
   性能测试结果如下,可以看到Span的速度是很快的,且不占内存。
https://img2023.cnblogs.com/blog/2281532/202311/2281532-20231107111213973-2133186639.png
 
 4. 切片

  Span.Slice()方法就是对内存进行切片,第三种方法区别于前两种,本质上不创建和销毁对象,可以认为是做到了内存0分配
5. ReadOnlySpan

  ReadOnlySpan是Span的只读表示形式,通常用在string的切片(因为string的不可变性)
https://img2023.cnblogs.com/blog/2281532/202311/2281532-20231107123414601-1410459990.png
 
 6. Span局限性


[*]Span是仅限存活在堆栈上的值类型
[*]Span不能是非堆栈类型的字段
[*]Span不能被装箱
[*]Span不能是异步方法的参数或局部变量
[*]Span不能被lambda表达式捕获

来源:https://www.cnblogs.com/YKAndXLL520/archive/2023/11/07/17814671.html
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!
页: [1]
查看完整版本: 编写高性能C#代码 —— Span<T>