查看: 816|回复: 5

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

[复制链接]

签到天数: 748 天

连续签到: 5 天

[LV.9]以坛为家II

57

主题

3320

积分

170

支持

发表于 2017-11-22 22:29:58 来自手机 | 显示全部楼层 |阅读模式

马上注册,享受积分奖励和更多功能,让您轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?注册

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

ReadOnlySpan 是 nuget 包 System.Memory 里的一个结构体。它统一一段存储空间,并且对这段存储空间提供能够在安全代码访问读取内容的属性。
被统一的空间可以用 stackalloc 出的基础值类型指针, 堆分配的数据的 void*, 一维数组, 一维数组片段, 字符串 表示。
下面是性能测试。已知一个字符串,是 “试一下看看,这东西到底多好用?“ 。取字符串的前 5 个字符,对其中的 “看” 这个字计数。重复 一千万次。用时越短越好。
同时还进行兼容性测试。API 用 C# 写,调用方代码是 VB 代码。
API 代码:
[C#] 纯文本查看 复制代码
public class CharCounter
    {
        public int CountOf(string str, char ch)
        {
            int count = 0;
            for (int i = 0; i < str.Length; i++)
            {
                if (str[i] == 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[i] == ch)
                {
                    count++;
                }
            }
            return count;
        }

        public int CountOf(char[] str, char ch)
        {
            int count = 0;
            for (int i = 0; i < str.Length; i++)
            {
                if (str[i] == ch)
                {
                    count++;
                }
            }
            return count;
        }
    }

调用代码:
[Visual Basic .NET] 纯文本查看 复制代码
    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

环境和编译选项:
.NET Core 2.0.2, x64, Release
结果:




ReadOnlySpan 节约了一半的时间!

那么,强行采用函数式编程风格压缩代码并添加一些额外的执行时间,ReadOnlySpan 优势还在吗?
根本不用担心它的优势消失。


来自:68861B8 WIN10 PC版客户端

签到天数: 624 天

连续签到: 1 天

[LV.9]以坛为家II

25

主题

1328

积分

0

支持

发表于 2017-11-22 23:03:36 | 显示全部楼层
666666666!可以的!
[你知道吗]:

签到天数: 671 天

连续签到: 32 天

[LV.9]以坛为家II

24

主题

1667

积分

283

支持

发表于 2017-11-23 01:14:01 来自手机 | 显示全部楼层
这个可以用来取代string么?System.Memory是.net core的命名空间?

来自:Lumia 950 XL Win10旗舰-智机社区客户端
[你知道吗]:

签到天数: 748 天

连续签到: 5 天

[LV.9]以坛为家II

57

主题

3320

积分

170

支持

 楼主| 发表于 2017-11-23 08:58:58 来自手机 | 显示全部楼层
player2135 发表于 2017-11-23 01:14
这个可以用来取代string么?System.Memory是.net core的命名空间?

在一些场景下可以取代字符串。System.Memory 是 nuget 包的名字,命名空间是 System。
来自:68861B8 WIN10 PC版客户端

签到天数: 671 天

连续签到: 32 天

[LV.9]以坛为家II

24

主题

1667

积分

283

支持

发表于 2017-11-23 09:40:10 来自手机 | 显示全部楼层
tmp00000 发表于 2017-11-23 08:58
在一些场景下可以取代字符串。System.Memory 是 nuget 包的名字,命名空间是 System。 ...

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

来自:Lumia 950 XL Win10旗舰-智机社区客户端
[你知道吗]:

签到天数: 748 天

连续签到: 5 天

[LV.9]以坛为家II

57

主题

3320

积分

170

支持

 楼主| 发表于 2017-11-23 18:40:40 来自手机 | 显示全部楼层
player2135 发表于 2017-11-23 09:40
不错啊,是微软官方提供的?

.NET Foundation 官方的。corefxlab 上可以看源码。这个包是用 C# 7.2 写的。
来自:68861B8 WIN10 PC版客户端
您需要登录后才可以回帖 登录 | 注册

本版积分规则

         

网站地图| 小黑屋|京ICP证150706号|京B2-20160045| 京公网安备11010802018258号

Powered by Discuz! X3.2 / Copyright 2010-2017 © 智机网 WFUN.COM Inc. All rights reserved.

快速回复 返回顶部 返回列表