.NET/C# 使用 Span 为字符串处理提升性能
.NET Core 2.1 和 C# 7.2 带来了 Span 的原生支持,原本需要使用不安全代码操作的内存块现在可以使用安全的方式来完成。此前在性能和稳定性上需要有所取舍,而现在可以兼得了。
简单的例子
先来看一个字符串处理时使用 Span<T> 的最简单的例子:
using System;
using System.Text;
namespace Walterlv.Demo.StringSpan
{
internal class Program
{
static void Main(string[] args)
{
var text = "https://walterlv.github.io/";
var nameSpan = text.AsSpan(8, 8);
var builder = new StringBuilder("Hello ");
builder.Append(nameSpan);
builder.AppendLine("!");
Console.WriteLine(builder.ToString());
}
}
}
这个例子是从 https://walterlv.github.io/ 字符串中取出第 8 个字符开始长度为 8 的部分,随后与其它字符串进行拼接。最后,我们得到了拼接的字符串:
这种方式取出字符串替代了 SubString 这种会额外生成临时字符串的方式。如果上述代码发生在较大或较多文本的处理中,那么反复的拼接将生成大量的临时字符串,造成大量 GC 压力;而使用 Span<T> 将不会额外生成任何临时字符串。
语言/框架的支持
然而,只有 .NET Core 2.1 是原生支持字符串的 AsSpan<T> 方法的,.NET Core 2.0、.NET Framework 4.7.2 是不支持的。.NET Core 2.0 可以无视,因为有了 2.1。但 .NET Framework 的低版本却不能无视,因为用户的计算机上通常都是安装低版本的 .NET Framework。
然而我们可以安装 System.Memory,以在低版本的 .NET 中获得字符串扩展方法 AsSpan<T> 的支持。
那么问题来了,低版本的 .NET StringBuilder 中并没有提供 Append(ReadOnlySpan<char>) 方法,于是我们即便使用高性能的方式得到了字符串的一个片段,依然无法将其反复进行拼接。
这真是一个悲伤的故事!
低版本 .NET 中有限的字符串性能提升
缺少了 StringBuilder 对 ReadOnlySpan<char> 的支持,广泛使用的字符串拼接功能便没有办法获得 Span 的支持。
不过,System.Memory 中提供了其它有限的字符串处理支持,来源于以下两个类型:
System.Buffers.Text.Utf8ParserSystem.Buffers.Text.Utf8Formatter
前者提供从 ReadOnlySpan<char> 到 Int32、Double、DateTime、Guid 等类型的解析,后者提供相反的转换。
期待 Microsoft 在未来版本的 System.Memory 库中提供对字符串拼接在低版本 .NET 生态中的支持。
参考资料
- Welcome to C# 7.2 and Span - .NET Blog
- C# 7.2: Understanding Span - Connect(); 2017 - Channel 9
- C# Span 入门
.NET/C# 使用 Span 为字符串处理提升性能的更多相关文章
- Span<T>和ValueTuple<T>性能是.Net Core非常关键的特性
Span<T>和ValueTuple<T> 性能是.Net Core一个非常关键的特性,今天我们重点研究一下ValueTuple<T>和Span<T>. ...
- paip.提升性能----数据库连接池以及线程池以及对象池
paip.提升性能----数据库连接池以及线程池以及对象池 目录:数据库连接池c3po,线程池ExecutorService:Jakartacommons-pool对象池 作者Attilax 艾龙, ...
- 从零开始写一个武侠冒险游戏-7-用GPU提升性能(2)
从零开始写一个武侠冒险游戏-7-用GPU提升性能(2) ----把地图处理放在GPU上 作者:FreeBlues 修订记录 2016.06.21 初稿完成. 2016.08.06 增加对 XCode ...
- 从零开始写一个武侠冒险游戏-6-用GPU提升性能(1)
从零开始写一个武侠冒险游戏-6-用GPU提升性能(1) ----把帧动画的实现放在GPU上 作者:FreeBlues 修订记录 2016.06.19 初稿完成. 2016.08.05 增加对 XCod ...
- 深入剖析虚拟DOM提升性能(Vue,React);
I.原始渲染方式(直接操作DOM): 1.state数据: 2.JSX模板: 3.数据 + 模板 相结合,生成真实的DOM来显示: 4.state发生改变: 5.数据 + 模板结合,生成真实的DOM来 ...
- [NewLife.XCode]扩展属性(替代多表关联Join提升性能)
NewLife.XCode是一个有10多年历史的开源数据中间件,支持nfx/netstandard,由新生命团队(2002~2019)开发完成并维护至今,以下简称XCode. 整个系列教程会大量结合示 ...
- [NewLife.XCode]高级查询(化繁为简、分页提升性能)
NewLife.XCode是一个有10多年历史的开源数据中间件,支持nfx/netcore,由新生命团队(2002~2019)开发完成并维护至今,以下简称XCode. 整个系列教程会大量结合示例代码和 ...
- 通过jdbc使用PreparedStatement,提升性能,防止sql注入
为什么要使用PreparedStatement? 一.通过PreparedStatement提升性能 Statement主要用于执行静态SQL语句,即内容固定不变的SQL语句.Statement每执行 ...
- SQL Server中使用Check约束提升性能
在SQL Server中,SQL语句的执行是依赖查询优化器生成的执行计划,而执行计划的好坏直接关乎执行性能. 在查询优化器生成执行计划过程中,需要参考元数据来尽可能生成高效的执行计划, ...
随机推荐
- PE文件格式学习之PE头移位
以前刚开始学网络安全,是从免杀开始的.记得那时候杀毒软件还很弱.金山江民瑞星还存在. 那会什么原理也不懂,就一直瞎鼓捣.(后来转入渗透行列了) 这段时间一直在学PE格式,突然想起来以前很古老的PE文件 ...
- JavaScript高级程序设计-读书笔记(3)
第8章 BOM 1.window对象 (1)全局作用域 BOM的核心对象是window,它表示浏览器的一个实例.在浏览器中,window对象既是通过JavaScript访问浏览器窗口的一个接口,又是E ...
- no crontab for root 解决方案
root用户下 输入 crontab -l 显示 no crontab for root 例如: [root@localhost ~]# crontab -l no crontab for root ...
- react native easter的分享
React 可以看做是连接native与JavaScript的桥梁bridge: 实现用js语言时间app的开发: 即使你不知道native是什么:
- ubuntu 14.04 如何安装nvidia显卡驱动 [转载]
我的机子装的是64位ubuntu 14.04 LTS系统,显卡是GeForce 405 ,想使用cuda所以需要装NVidia官方驱动,但是总是碰到 nouveau 驱动正在使用的问题.找了好久,网上 ...
- [JS]JavaScript判断操作系统版本
function detectOS() { var sUserAgent = navigator.userAgent; var isWin = (navigator.platform == " ...
- sql 日志统计-日、周、月活跃数
近日网站需求:统计日志表的 日.周.月活跃数.最终研究了出来了,分享给大家看下. 如果有更好的sql语句也可以评论下方. --日活跃量 ), cr.AddTime, )as addtimt,COUN ...
- Qt实现简单的单例模式
单例模式十分的常见也很常用,Boost库中就有单例的泛型实现,Qt中,可以利用原子指针来实现一个单例模式: class SingleTon{ public: static SingleTon & ...
- PHP回调函数call_user_func()和call_user_func_array()的使用
call_user_func():把第一个参数作为回调函数调用 用法:call_user_func ( callable $callback [, mixed $parameter [, mixed ...
- mysql的sql编程
sql编程 变量 变量分为两种:系统变量和自定义变量 系统变量 系统定义好的变量:大部分的时候用户根本不需要使用系统变量,系统变量时用来控制服务器的表现的,如:auto_commit. 查看系统变量 ...