.NET Core中妙用unsafe减少gc提升字符串处理性能
一、前言
昨天在群里讨论怎么样效率的把一个字符串进行反转,一般的情况我们都知道,只要对String对象进行操作,
那么就会生成新的String对象,比如"1"+"2" 这样的操作会生成新的String对象。
二、通正方案
通常我们要反转一个字符中我们都是使用如下方法:
static string Reverse1(string original)
{
char[] arr = original.ToCharArray();
Array.Reverse(arr);
return new string(arr);
}
这种方式,只是通过将数组反转的方式重新排列了字符的顺序,最终还是要重新生成新的String对象,这样无疑会在数据量比较大的时候,会增加GC负担的。
三、unsafe方案
本文主要想讲述使用**unsafe**的方式来优化性能,当然在最后面还提到了**c# 7.0**中的新特性来实现相同功能。
unsafe关键字表示不安全上下文,该上下文是任何涉及指针的操作所必需的。有关更多信息,请参见不安全代码和指针(C# 编程指南)。
可以在类型或成员的声明中使用 unsafe 修饰符。因此,类型或成员的整个正文范围均被视为不安全上下文。
c#在默认情况下生成的都是安全代码,即进行了代码托管(.NET的CLR机制好处之一就是自动进行代码托管,适时的释放内存,程序员便不必考虑资源的回收问题),而此时,指针不能出现在安全代码的编译条件下。
如果因需要想在c#中使用指针,那么unsafe便是一个通道(当然在使用前,需在项目属性的生成选项中,选择“允许不安全代码”)。
直接上代码吧:
string hello = "hello world你好"; int len = hello.Length * ; fixed (char* strs = hello)
{
byte* start = (byte*)strs;
byte* end = start + len - ;
byte[] ch = new byte[];
if (start != null)
{
while (start < end)
{
ch[] = *start;
ch[] = *(start + ); *start = *(end-);
*(start+) = *(end); start = start + ; *(end - ) = ch[];
*(end) = ch[]; end = end - ;
}
} }
fixed 语句设置指向托管变量的指针并在 statement 执行期间“钉住”该变量。如果没有 fixed 语句,则指向可移动托管变量的指针的作用很小,因为垃圾回收可能不可预知地重定位变量。C# 编译器只允许在 fixed 语句中分配指向托管变量的指针。(这句话是机器翻译的,呵呵)
好了最终的结果就是: hello="好你dlrow olleh" , 但是我们并没有new String哦!
四、C#7 Ref locals ?
其实对说新的C# 7.0来说,它为我们带来了新ref关键字,来处理本地引用(Ref locals )。
让我们来开一下脑洞,下面是段成立的代码:
string hello = "hello world你好";
ref char strRef = ref getStringArray(ss, ); static ref char getStringArray(char[] str,int index)
{
return ref str[index];
}
strRef是什么?我们是不是可以通过这样的方式,来达到与使用指针相同的目地?请继续关注下一篇文章。
同时宣传一下我的新博客,当然博客园我也会更新的。 http://www.dotnet.ren
.NET Core中妙用unsafe减少gc提升字符串处理性能的更多相关文章
- .net core中关于System.Text.Json的使用
在.Net Framework的时候序列化经常使用Newtonsoft.Json插件来使用,而在.Net Core中自带了System.Text.Json,号称性能更好,今天抽空就来捣鼓一下. 使用起 ...
- asp.net core中IHttpContextAccessor和HttpContextAccessor的妙用
分享一篇文章,关于asp.net core中httpcontext的拓展. 现在,试图围绕HttpContext.Current构建你的代码真的不是一个好主意,但是我想如果你正在迁移一个企业类型的应用 ...
- 工厂参观记:.NET Core 中 HttpClientFactory 如何解决 HttpClient 臭名昭著的问题
在 .NET Framework 与 .NET Core 中 HttpClient 有个臭名昭著的问题,HttpClient 实现了 IDispose 接口,但当你 Dispose 它时,它不会立即关 ...
- ASP.NET Core中的依赖注入(4): 构造函数的选择与服务生命周期管理
ServiceProvider最终提供的服务实例都是根据对应的ServiceDescriptor创建的,对于一个具体的ServiceDescriptor对象来说,如果它的ImplementationI ...
- ASP.NET Core 中文文档 第三章 原理(6)全球化与本地化
原文:Globalization and localization 作者:Rick Anderson.Damien Bowden.Bart Calixto.Nadeem Afana 翻译:谢炀(Kil ...
- ASP.NET Core 中文文档 第三章 原理(15)请求功能
作者:Steve Smith 翻译:谢炀(kiler398) 校对:姚阿勇(Dr.Yao).孟帅洋(书缘) 涉及到如何处理 HTTP 请求以及响应的独立 Web 服务器功能已经被分解成独立的接口,这些 ...
- 减少GC开销的措施
程序的运行会直接影响系统环境的变化,从而影响GC的触发.若不针对GC的特点进行设计和编码,就会出现内存驻留等一系列负面影响.为了避免这些影响,基本的原则就是尽可能地减少垃圾和减少GC过程中的开销.具体 ...
- 减少GC开销的5个编码技巧
在这篇文章中,我们来了解一下让代码变得高效的五种技巧,这些技巧可以使我们的垃圾收集器(GC)在分配内存以及释放内存上面,占用更少的CPU时间,减少GC的开销.当内存被回收的时候,GC处理很长时间经常会 ...
- 最近发现的.net core中的一些bugs
1.使用.net core的过程中发现TypeInfo.GetCustomAttributes()只能写在主线程中,否则如果该自定义特性存在于nuget中就会报错,貌似nuget中的dll仅在主线程使 ...
随机推荐
- Django form模块使用心得
最近用Django 写了一个网站,现在来分享一下对Django form 的一些心得. 一,创建一个表单 创建一个Form表单有两种方式: 第一种方式是继承于forms.Form,的一个子类,通过在f ...
- 用python实现模拟登录人人网
用python实现模拟登录人人网 字数4068 阅读1762 评论19 喜欢46 我决定从头说起.懂的人可以快速略过前面理论看最后几张图. web基础知识 从OSI参考模型(从低到高:物理层,数据链路 ...
- C # 产生鼠标点击事件
新建一个WinFrom,找到MouseDown,回车,生成代码如下点击的效果如图 参考文章:http://blog.csdn.net/u012842807/article/details/454143 ...
- Jenkins中deploy插件的deploy war/ear to a container与deploy artifacts to maven reepository区别
deploy war/ear to a container:发布war包到服务器 deploy artifacts to maven reepository:发布到maven服务器
- dbf导入sqlserver的方法
1. dbf导出为foxpro2.x. 2.打开excel,点击打开,选择dbase文件,选中第一步保存的文件. 3.另存为xls格式 4.使用sql的dts导入xls.
- MVC伪一个12306图片验证码
本文的来由主要是满足自己的好奇心,而不是证明什么东西,如果涉及到什么官方性的事情,麻烦通知我谢谢:本篇将要和大家分享的是一个看起来通12306图片验证码相似的效果,这篇应该是今年农历最后一篇分享文章了 ...
- ASP.NET 页面之间传值的几种方式
开篇概述 对于任何一个初学者来说,页面之间传值可谓是必经之路,却又是他们的难点.其实,对大部分高手来说,未必不是难点. 回想2016年面试的将近300人中,有实习生,有应届毕业生,有1-3年经验的,有 ...
- MyBatis-Generator的配置说明和使用
关于MyBatis: MyBatis Generator (MBG) 是一个Mybatis的代码生成器 MyBatis 和 iBATIS. 他可以生成Mybatis各个版本的代码,和iBATIS 2. ...
- python中关于元组的操作
元组的基本操作:1.创建一个元组: tuple=(1,26); tuple1=(","sy"); 创建一个空元组: tuple=(); 元组中只包含一个元素时,需要在元素 ...
- C++ 头文件系列(forward_list)
简介 forwrad_list字面意思为前向列表,但实际上它是一种单向列表,只能从单一方向遍历. 单向链表实现 forward_list内部是用单向列表实现的,并且设计该库的时候就是以近乎手写的单向链 ...