.NET Core中妙用unsafe减小gc提高字符串处理性能

1、前言

昨天在群里讨论怎么样效率的把一个字符串进行反转,通常的状况咱们都知道,只要对String对象进行操做,
那么就会生成新的String对象,好比"1"+"2" 这样的操做会生成新的String对象。程序员

2、通正方案

一般咱们要反转一个字符中咱们都是使用以下方法:编程

static string Reverse1(string original)
{
    char[] arr = original.ToCharArray();
    Array.Reverse(arr);
    return new string(arr);
}

这种方式,只是经过将数组反转的方式从新排列了字符的顺序,最终仍是要从新生成新的String对象,这样无疑会在数据量比较大的时候,会增长GC负担的。c#

3、unsafe方案

本文主要想讲述使用**unsafe**的方式来优化性能,固然在最后面还提到了**c# 7.0**中的新特性来实现相同功能。数组

unsafe关键字表示不安全上下文,该上下文是任何涉及指针的操做所必需的。有关更多信息,请参见不安全代码和指针(C# 编程指南)。安全

能够在类型或成员的声明中使用 unsafe 修饰符。所以,类型或成员的整个正文范围均被视为不安全上下文。性能

c#在默认状况下生成的都是安全代码,即进行了代码托管(.NET的CLR机制好处之一就是自动进行代码托管,适时的释放内存,程序员便没必要考虑资源的回收问题),而此时,指针不能出如今安全代码的编译条件下。
若是因须要想在c#中使用指针,那么unsafe即是一个通道(固然在使用前,需在项目属性的生成选项中,选择“容许不安全代码”)。优化

直接上代码吧:spa

string hello = "hello world你好";

int len = hello.Length * 2;

fixed (char* strs = hello)
{
    byte* start = (byte*)strs;
    byte* end = start + len - 1;
    byte[] ch = new byte[2];
    if (start != null)
    {
        while (start < end)
        {
            ch[0] = *start;
            ch[1] = *(start + 1);

            *start = *(end-1);
            *(start+1) = *(end);

            start = start + 2;

            *(end - 1) = ch[0];
            *(end) = ch[1];

            end = end - 2;
        }
    }

}

fixed 语句设置指向托管变量的指针并在 statement 执行期间“钉住”该变量。若是没有 fixed 语句,则指向可移动托管变量的指针的做用很小,由于垃圾回收可能不可预知地重定位变量。C# 编译器只容许在 fixed 语句中分配指向托管变量的指针。(这句话是机器翻译的,呵呵)翻译

好了最终的结果就是: hello="好你dlrow olleh" , 可是咱们并无new String哦!指针

4、C#7 Ref locals ?

其实对说新的C# 7.0来讲,它为咱们带来了新ref关键字,来处理本地引用(Ref locals )。

让咱们来开一下脑洞,下面是段成立的代码:

 

string hello = "hello world你好";
ref char strRef = ref getStringArray(ss, 0);

static ref char getStringArray(char[] str,int index)
{
    return ref str[index];
}

strRef是什么?咱们是否是能够经过这样的方式,来达到与使用指针相同的目地?请继续关注下一篇文章。

 

同时宣传一下个人新博客,固然博客园我也会更新的。  http://www.dotnet.ren

相关文章
相关标签/搜索