.NET点滴:Span<T;

Posted dotNET跨平台

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了.NET点滴:Span<T;相关的知识,希望对你有一定的参考价值。

昨天小桂问了一个问题,把一个数组的全部元素加1,有什么好办法,于是有了下面的分析:

var arr = new int[]  1, 2, 3, 4, 5, 6, 7, 8, 9 ;
//方法一
foreach (var i in arr)

    i++;

//方法二
for (var i = 0; i < arr.Length; i++)

    arr[i] += 1;

//方法三
foreach (ref var i in arr.AsSpan())

    i++;

方法一在编译时会报错的,提示如下:无法为"i"赋值,因为它是"foreach"迭代变量,foreach循环时,是通过yield return返回的只读数据,所以不能给它赋值。

方法二没有问题,遍历元素,轮询加1。

方法三比较有意思了,是通过Span<T>来用ref(可以理解成指针,或引用)的方式来,来指向数组的元素,实现加1。

关于Span<T>,借用官方的一句话:“由于 Span<T> 是任意内存块(可以是托管内存,本机内存,堆栈内存)的抽象,因此 Span<T> 具有参数的类型和方法的方法将 Span<T> 在任何对象上操作, Span<T> 而不考虑它所封装的内存类型。”,可以清楚的理解Span<T>的专门作用。

关于方法二和方法三的性能怎么样,下来是测试代码和结果,供大家参考:

using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Running;


BenchmarkRunner.Run<TestSpan>();


public class TestSpan

    [Benchmark]
    public void Demo1()
    
        var arr = new int[]  1, 2, 3, 4, 5, 6, 7, 8, 9 ;
        foreach (ref var i in arr.AsSpan())
        
            i++;
        
    


    [Benchmark]
    public void Demo2()
    
        var arr = new int[]  1, 2, 3, 4, 5, 6, 7, 8, 9 ;
        for (var i = 0; i < arr.Length; i++)
        
            arr[i] += 1;
        
    

结果:

以上是关于.NET点滴:Span<T;的主要内容,如果未能解决你的问题,请参考以下文章

如何将 C# 字符串转换为 Span<char>? (跨度<T>)

在 C# 中使用 Span<T; 和 Memory<T; 编写高性能代码

Autofac 的点滴

C# 7.2 中的 Span<T> 和 Memory<T> 有啥区别?

.NET点滴:说说Middleware构造中获取不到Scoped服务的问题

linux的点滴积累