2015年2月8日 星期日

[C#] string 串接 P.K StringBuilder

近日因需要增進程式的效能,檢查了可能提昇效能的方式,前人留下來的程式碼中,有一段

需大量執行字串的串接   ex: s+= xx   ,s 是一個string, xx是一個變數,隨著執行階段的資料

而改變, 程式中出現串接s變數的有數十次(前人辛苦了),決定從這裡開刀。


查到一篇文章是這麼寫的:


大部分的.NET開發者都知道,要做大量的字串相加,StringBuilder比string相加快上N倍。這

個效能差異源於String物件的特性,每次"動態相加"時必須捨棄原字串佔用的記憶體空間,重

新配置記憶體儲存相加後的新字串內容。只是背後的原理實在曲折,於是我們腦海只會留

下"串接字串千萬要用StringBuilder,用string相加會被人笑"的簡化結論。


最後,主測試後得出了結論:


以StringBuilder提升字串相加效率主要應用於大量的反覆字串動態(in runtime)串接,靜態字

串的串接在編譯時就會自動變成單一字串,牽扯到StringBuilder物件的建立與呼叫反而變慢

許多。因此StringBuilder請應用在連續大量的Runtime動態字串相接才不會未得其利,反受其

害。


資料來源-StringBuilder串接字串的迷思


所以只有在使用大量動態字串做串接時,用StringBuilder才會有良好的效果,恰巧符合俺滴

情況,在把string 換成用StringBuilder後確實得到了明顯的改善,以下我們用一個簡單的例

子,來比較一下執行一萬次的動態串接,用string 及StringBuilder差異在什麼地方。


using System.IO;
using System;
using System.Text;

class Program
{
    static void Main()
    {
        System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();//引用stopwatch物件
        sw.Reset();//碼表歸零
        sw.Start();//碼表開始計時

        string a="";
        
        for (int i=0;i<10000;i++)
       {
           a+=i.ToString() ;
       }
        sw.Stop();//碼錶停止
        //印出所花費的總豪秒數
        string result1 = sw.Elapsed.TotalMilliseconds.ToString();
        Console.WriteLine("string: "+result1+" ms");
        sw.Reset();//碼表歸零
        sw.Start();//碼表開始計時
        StringBuilder b=new StringBuilder();
        
        for (int i=0;i<10000;i++)
       {
           b.Append(i);
       }
        sw.Stop();//碼錶停止
        //印出所花費的總豪秒數
        result1 = sw.Elapsed.TotalMilliseconds.ToString();
        Console.WriteLine("StringBuilder: "+result1+" ms");
    }
}


執行結果







速度相差 258倍,StringBuilder在動態串接完勝。

1 則留言:

  1. Great article. I love how you talked about the trouble freelance platforms face while hiring a remote developer. I also know about one freelancing platform that is Eiliana.com. It is a new and great platform for technical experts. They have some amazing strategies for hiring developers, and you should connect with them.

    回覆刪除