System.ReadOnlySpan 到底有多快?眼见为实!

tmp00000 UID.995403
2017-11-22 发表

本帖最后由 tmp00000 于 2017-11-22 23:33 编辑

ReadOnlySpan 是 nuget 包 System.Memory 里的一个结构体。它统一一段存储空间,并且对这段存储空间提供能够在安全代码访问读取内容的属性。 被统一的空间可以用 stackalloc 出的基础值类型指针, 堆分配的数据的 void*, 一维数组, 一维数组片段, 字符串 表示。 下面是性能测试。已知一个字符串,是 “试一下看看,这东西到底多好用?“ 。取字符串的前 5 个字符,对其中的 “看” 这个字计数。重复 一千万次。用时越短越好。 同时还进行兼容性测试。API 用 C# 写,调用方代码是 VB 代码。 API 代码: [mw_shl_code=csharp,true]public class CharCounter { public int CountOf(string str, char ch) { int count = 0; for (int i = 0; i < str.Length; i++) { if (str == ch) { count++; } } return count; } public int CountOf(ReadOnlySpan<char> str, char ch) { int count = 0; for (int i = 0; i < str.Length; i++) { if (str == ch) { count++; } } return count; } public int CountOf(char[] str, char ch) { int count = 0; for (int i = 0; i < str.Length; i++) { if (str == ch) { count++; } } return count; } }[/mw_shl_code] 调用代码: [mw_shl_code=vbnet,true] Sub Main(args As String()) Dim counter As New CharCounter Dim kan% ' 程序的目标:取字符串的前 5 个字符,对其中的 “看” 这个字计数。重复 一千万次。 Const StringToAccess = “试一下看看,这东西到底多好用?“ With New Stopwatch For r = 1 To 5 Console.WriteLine($“=== 第 { r } 次测试 ===“) ' 新 API 的测试 .Restart() For i = 0 To 1000_0000 kan = counter.CountOf(StringToAccess.AsSpan.Slice(0, 5), “看“c) Next .Stop() Console.WriteLine($“使用 ReadOnlySpan: { .ElapsedMilliseconds}ms“) ' 之前一直在用 String .Restart() For i = 0 To 1000_0000 kan = counter.CountOf(StringToAccess.Substring(0, 5), “看“c) Next .Stop() Console.WriteLine($“使用传统的 String: { .ElapsedMilliseconds}ms“) ' 曾经被寄予厚望的 Char 数组 .Restart() For i = 0 To 1000_0000 Dim buf(4) As Char StringToAccess.CopyTo(0, buf, 0, 5) kan = counter.CountOf(buf, “看“c) Next .Stop() Console.WriteLine($“使用 Char 数组: { .ElapsedMilliseconds}ms“) Next End With Console.WriteLine(“测试完毕,按回车键退出。“) Console.ReadLine() End Sub[/mw_shl_code] 环境和编译选项: .NET Core 2.0.2, x64, Release 结果: ***图片停止解析*** ReadOnlySpan 节约了一半的时间! 那么,强行采用函数式编程风格压缩代码并添加一些额外的执行时间,ReadOnlySpan 优势还在吗? 根本不用担心它的优势消失。
***图片停止解析***

敬告:
为防止不可控的内容风险,本站已关闭新用户注册,新贴的发表及评论;
你现在看到的内容只是互联网用户曾经发表的言论快照,仅用于老用户留存纪念,且仅与科技行业相关,全部内容不代表本站观点及立场;
本站重新开放前已针对包括用户隐私、版权保护、信息安全、国家政策在内的各种互联网法律法规要求,执行了隐患内容的自查、屏蔽和删除;
本站目前所属个人主体,未有任何盈利安排与计划,且与原WFUN.COM所属公司不存在任何关联关系;
如果本帖内容或者相关资源侵犯到您的合法权益,或者您认为存在问题,那么请您务必点此举报或投诉!
全部回复:
笨丶苽苽 UID.1017039
2017-11-22 回复

666666666!可以的!

player2135 UID.664133
2017-11-23 使用 Lumia 950 XL 回复

这个可以用来取代string么?System.Memory是.net core的命名空间?

tmp00000 UID.995403
2017-11-23 回复

Quoteplayer2135 发表于 2017-11-23 01:14
这个可以用来取代string么?System.Memory是.net core的命名空间?


在一些场景下可以取代字符串。System.Memory 是 nuget 包的名字,命名空间是 System。

player2135 UID.664133
2017-11-23 使用 Lumia 950 XL 回复

Quotetmp00000 发表于 2017-11-23 08:58
在一些场景下可以取代字符串。System.Memory 是 nuget 包的名字,命名空间是 System。 ...


不错啊,是微软官方提供的?

tmp00000 UID.995403
2017-11-23 回复

Quoteplayer2135 发表于 2017-11-23 09:40
不错啊,是微软官方提供的?


.NET Foundation 官方的。corefxlab 上可以看源码。这个包是用 C# 7.2 写的。

artfly08 UID.2900999
2018-06-26 使用 Lumia 950 XL 回复

厉害

artfly08 UID.2900999
2018-07-14 使用 Lumia 950 XL 回复

支持

本站使用Golang构建,点击此处申请开源鄂ICP备18029942号-4联系站长投诉/举报