StringJoiner 拯救那些效能低下的字串拼裝程式碼
前言
一般程式設計師所擁有最“強”的兩件武器就是:複製和粘帖。
String
這篇文章是想介紹大家一個小技巧。
我們知道,或者第一天學習C#的時候就認識string型別,然後很快就知道最簡單的拼裝string的寫法:
string s = string.Empty; s += "Bruce"; s += "Who?"; s += "a guy think sth different...";
這種寫法實在是太簡單太美好了,因為相比C語言的 strcat 寫法,使用C#實在是太幸福了。而且不知道什麼時候還支援這種寫法:
s += "Bruce" + " Lee";
(我實在不知道什麼時候開始支援以上寫法,記得.Net2.0是不能這樣寫的,如果是.Net1.1肯定不行,一定要加括號:
s += ("Bruce" + " Lee");
)
StringBuilder
然而,這種幸福感可能導致初學者不知道StringBuilder的存在,偶爾在其他人的文章上看到StringBuilder,可能也是不瞭解為什麼有“+=”不用,要寫上一堆 Append ...
StringBuilder sb = new StringBuilder(); sb.Append("Bruce"); sb.Append("Who?"); sb.Append("a guy think sth different...");
你或許不相信,我估計在企業裡從事.Net工作一兩年的朋友,還是有人不知道StringBuilder的存在。特別在 Asp.Net 裡,不少朋友喜歡用C#拼裝一堆前臺程式碼,如Html語句或JavaScript,甚至SQL語句 … 他們無一例外都是使用“+=”來拼接,然後拍拍屁股就走人了,留下幾十行,甚至上百行這樣的語句。
我們應該知道,使用第一種方式來拼接字串,無論是從時間或空間的效能來說,都遠不如使用StringBuilder。
好孩子看到這裡,可能就會趕快回去把自己那段“+=”全換上StringBuilder的 Append方法。先別急,畢竟由方式一向方式二轉換是很費時間的,絕對是苦力活,我現在要告訴大家怎麼以最快速使方式一的程式碼效能上升到方式二。
StringJoiner
很簡單,把 string s 改成 StringJoiner s 就大功告成。即
StringJoiner s = string.Empty; s += "Bruce"; s += "Who?"; s += "a guy think sth different...";
咋這麼簡單就提高效能?忽悠我?
當然不是忽悠大家,也不是玩魔術,文章末會有效能測試資料,有圖有真相。
現在讓我來揭開 StringJoiner 的面紗,最後你肯定會說:原來這麼簡單。
StringJoiner 其實是類似裝飾者模式,對外隱藏了StringBuilder ,就像魔術師喜歡把一堆道具藏到袖子,以忽悠觀眾那樣。
public class StringJoiner { protected StringBuilder Builder; public StringJoiner() { Builder = new StringBuilder(); } }
(把Builder定義成protected ,期待某天可能需要繼承StringJoiner 來繼續“忽悠觀眾”)
StringJoiner 是怎麼實現剛才的程式碼?
1.隱式轉換
如:
StringJoiner s = string.Empty;
的謎底是:
public static implicit operator StringJoiner(string value) { StringJoiner text = new StringJoiner(); text.Builder.Append(value); return text; }
(新建一個物件,把賦值轉移到 StringBuilder 的Append方法)
2. 過載操作符
如:
s += "Bruce";
的謎底是:
public static StringJoiner operator +(StringJoiner self, string value) { self.Builder.Append(value); return self; }
(實現 StringJoiner 與 string 型別可以通過運算子“+”操作,同樣是把字串交給StringBuilder 的Append方法)
為了更通用,如實現與其他型別連線:
s += 123;
s += 0.314;
s += 'c';
因此,必須過載 StringJoiner + Object
public static StringJoiner operator +(StringJoiner self, object value) { self.Builder.Append(value); return self; }
最後,為了讓 StringJoiner 的“忽悠”水平更上一層樓,StringJoiner 的物件必須能夠隱式轉換成 string 型別:
public static implicit operator string(StringJoiner value) { return value.ToString(); } public override string ToString() { return this.Builder.ToString(); }
當然,到這一刻 StringJoiner 已經足夠了,更徹底的“忽悠”並不是本文的目的。 StringJoiner 並不是想替代string,更不是替代StringBuilder,反而我舉腳贊成使用StringBuilder。但如果你想重構一段由“string += ” 帶來的慘不忍睹的程式碼時,用StringJoiner 吧。
效能測試
效能計數器:CodeTimer (XP版)
測試程式碼(3種不同方法拼裝一萬次字串,接著拼裝一萬次整數,並重復10次以上操作):
static void Main(string[] args) { CodeTimer.Time("", 1, () => { }); //通過 += 拼裝字串 CodeTimer.Time("NormalString", 10, () => NormalString()); //StringJoiner 拼裝字串 CodeTimer.Time("StringJoiner", 10, () => StringJoiner()); //StringBuilder 拼裝字串 CodeTimer.Time("StringBuilder", 10, () => StringBuilder()); Console.WriteLine("continue..."); Console.Read(); } //拼裝字串長度 const int stringLength = 10000; static void NormalString() { string s = string.Empty; for (int i = 0; i < stringLength; i++) s += "A";//拼裝字串 s = string.Empty; for (int i = 0; i < stringLength; i++) s += 1;//拼裝整數 string result = s; } static void StringJoiner() { StringJoiner s = string.Empty; for (int i = 0; i < stringLength; i++) s += "A"; s = string.Empty; for (int i = 0; i < stringLength; i++) s += 1; string result = s; } static void StringBuilder() { StringBuilder s = new StringBuilder(string.Empty); for (int i = 0; i < stringLength; i++) s.Append("A"); s = new StringBuilder(string.Empty); for (int i = 0; i < stringLength; i++) s.Append(1); string result = s.ToString(); }
其中一次測試結果:
NormalString
Time Elapsed: 667ms
Time Elapsed (one time):66ms
CPU time: 671,875,000ns
CPU time (one time): 67,187,500ns
Gen 0: 1908
Gen 1: 0
Gen 2: 0
StringJoiner
Time Elapsed: 19ms
Time Elapsed (one time):1ms
CPU time: 15,625,000ns
CPU time (one time): 1,562,500ns
Gen 0: 3
Gen 1: 0
Gen 2: 0
StringBuilder
Time Elapsed: 19ms
Time Elapsed (one time):1ms
CPU time: 15,625,000ns
CPU time (one time): 1,562,500ns
Gen 0: 3
Gen 1: 0
Gen 2: 0
從上圖可以看到,StringJoiner 和 StringBuilder 效能持平,而它們都遠遠比第一種方法領先。
作者:Bruce(程式設計的藝術世界)
出處:http://coolcode.cnblogs.com
本文版權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段宣告,且在文章頁面明顯位置給出原文連線,否則保留追究法律責任的權利。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/12639172/viewspace-616446/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Java 8 StringJoiner字串聯結器Java字串
- Java 8中字串拼接新姿勢:StringJoinerJava字串
- 拯救你的Go程式碼Go
- 不以寫效率低下的程式為恥
- 不要試圖拯救那些職場上的那些“無可救藥”
- 低程式碼如何“拯救”企業?
- 一鍵fxxk,程式碼修復神器拯救你
- 聊聊那些年遇到過的奇葩程式碼
- 程式碼重構那些事兒
- 那些優雅靈性的JS程式碼片段JS
- 前端JS程式碼的效能探究前端JS
- 拯救php效能的神器webman-打包二進位制PHPWeb
- IndexedDB 程式碼封裝、效能摸索以及多標籤支援Index封裝
- Java連結c++動態庫實現字串的傳輸---簡單的字元拼裝返回JavaC++字串字元
- 拼多多開店如何運營,有那些技巧?
- 讓人疑惑的Java程式碼 – Java那些事兒Java
- 那些坑你沒商量的程式碼死迴圈
- 拯救php效能的神器webman-使用後臺webman-adminPHPWeb
- Python 程式碼的效能優化之道Python優化
- String字串效能優化的探究字串優化
- 拼多多商品詳情介面,拼多多百億補貼資料介面,拼多多優惠券介面程式碼教程
- Guava - 拯救垃圾程式碼,寫出優雅高效,效率提升N倍Guava
- surface安裝linux終極拯救指南Linux
- 拯救祭天的程式設計師——事件溯源模式程式設計師事件模式
- 小程式字串轉成二維碼遇到的坑字串
- 有助於改善效能的Java程式碼技巧Java
- 編寫高效能的Java程式碼Java
- iOS-效能最佳化的那些事iOS
- Java程式碼中字串拼接方式分析Java字串
- 你只會用 StringBuilder?試試 StringJoiner,真香!UI
- 寫了 20-50 年的程式碼,才明白的那些真理
- Java程式碼的編譯與反編譯那些事兒Java編譯
- axios中的那些天才程式碼!看完我實力大漲!iOS
- 刪除字串中的html標籤程式碼例項字串HTML
- 用 100 行程式碼提升 10 倍的效能行程
- 如何使用 Set 來提高程式碼的效能
- 軟體效能測試的內容有那些?
- jexl2 執行字串Java程式碼字串Java
- 去除字串中所有js,css程式碼類字串JSCSS