即日起在codingBlog上分享您的技术经验即可获得积分,积分可兑换现金哦。

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

微信 DotNet 15℃ 0评论

(点击上方蓝字,可快速关注我们)


来源:YOYOFx

cnblogs.com/maxzhang1985/p/6436178.html


一、前言

群里讨论怎么样效率的把一个字符串进行反转,一般的情况我们都知道,只要对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 * 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哦!

四、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是什么?我们是不是可以通过这样的方式,来达到与使用指针相同的目地?请继续关注下一篇文章。

看完本文有收获?请转发分享给更多人

关注「DotNet」,提升.Net技能 

转载请注明:CodingBlog » .NET Core中妙用unsafe减少gc提升字符串处理性能

喜欢 (0)or分享 (0)
发表我的评论
取消评论

*

表情
(1)个小伙伴在吐槽
  1. 请继续关注下一篇文章/发呆
    金奇2017-03-02 23:38 回复