不太会用Span<T> 看文档上的优点估摸着试试
本次采用最流行而又权威的benchmarkdotnet 基准测试库进行
因为确实看文档和网文上关于Span<T>的示例很少,最多就是切string, substring split方面的,具体意思感觉就是多次被调用时如果都在创建临时的数组对象会给gc带来负荷,而这正是Span<T>能解决的
目前我对Span<T>的理解是 在栈上的一块连续内存的安全抽象,当初始化的传入的 数组对象可以看成是该数组对象的一个引用别名。
下面是测试代码:
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. namespace Tester; using BenchmarkDotNet.Attributes; using BenchmarkDotNet.Configs; [SimpleJob(iterationCount: 100)] public class Test { [Params(20)] public int len; public int[] source; [GlobalSetup] public void Setup() { source = new int[len]; for (var i = 0; i < len; i++) { source[i] = i; } } [Benchmark] public int[] GetOddByGeneral() { var result = new int[len]; int _len = 0; for (var i = 0; i < len; i++) { if (source[i] % 2 == 1) { result[i] = source[i]; _len++; } } return result[0.._len]; } [Benchmark] public int[] GetOddBySpan() { Span<int> sourceSpan = stackalloc int[len]; int _len = 0; for (var i = 0; i < len; i++) { if (source[i] % 2 == 1) { sourceSpan[i] = source[i]; _len++; } } return sourceSpan.Slice(0, _len).ToArray(); } } public class Program { static void Main(string[] args) { var summary = BenchmarkDotNet.Running.BenchmarkRunner.Run<Test>( BenchmarkDotNet.Configs.DefaultConfig.Instance .WithSummaryStyle(BenchmarkDotNet.Reports.SummaryStyle.Default.WithMaxParameterColumnWidth(100)) ); Console.WriteLine(summary); } }
//结果截图
我不知道我设计这个测试逻辑是否合理,就从测试结果看确实 Span<T>有一点微弱的优势,可能是我代码逻辑不合理造成的,因为在general中我有多余的切片操作这其实是额外的应该避免的。
不过Span<T>方法里也有 slice 先算它们扯平。
在general方法中 每被调一次就会多一次创建数组的开销 逻辑上说会增加内存消耗,但具体什么情况我不知道。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
2018-11-04 npm 有用的一些全局包