System.ReadOnlySpan 到底有多快?眼见为实!
本帖最后由 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所属公司不存在任何关联关系;
如果本帖内容或者相关资源侵犯到您的合法权益,或者您认为存在问题,那么请您务必点此举报或投诉!
Quoteplayer2135 发表于 2017-11-23 01:14
这个可以用来取代string么?System.Memory是.net core的命名空间?
在一些场景下可以取代字符串。System.Memory 是 nuget 包的名字,命名空间是 System。
Quotetmp00000 发表于 2017-11-23 08:58
在一些场景下可以取代字符串。System.Memory 是 nuget 包的名字,命名空间是 System。 ...
不错啊,是微软官方提供的?
Quoteplayer2135 发表于 2017-11-23 09:40
不错啊,是微软官方提供的?
.NET Foundation 官方的。corefxlab 上可以看源码。这个包是用 C# 7.2 写的。