昨天在羣裏討論怎麼樣效率的把一個字符串進行反轉,通常的狀況咱們都知道,只要對String對象進行操做,
那麼就會生成新的String對象,好比"1"+"2" 這樣的操做會生成新的String對象。程序員
一般咱們要反轉一個字符中咱們都是使用以下方法:編程
static string Reverse1(string original) { char[] arr = original.ToCharArray(); Array.Reverse(arr); return new string(arr); }
這種方式,只是經過將數組反轉的方式從新排列了字符的順序,最終仍是要從新生成新的String對象,這樣無疑會在數據量比較大的時候,會增長GC負擔的。c#
本文主要想講述使用**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哦!指針
其實對說新的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