天天看點

dotnet程式優化心得(三)

(4)繼續優化――用空間換取時間

現在對每一個字元,都要用get_Item(object key)方法過一遍,可這個乖乖方法那麼長,肯定太耗時間了,能不能用更簡單的手段呢?改Hashtable?哇,那代碼,叫一個看不懂。仔細琢磨琢磨,有了,直接用數組!每一個漢字對應一個Int16,以該值為索引,數組中在那個位置的值為值,這樣最快速了。就是占點空間,記憶體便宜嘛。反正這東西隻初始化一次,占不了多少k。新程式如下:

 1

dotnet程式優化心得(三)

public class QuickChineseConvert

 2

dotnet程式優化心得(三)

{

 3

dotnet程式優化心得(三)

    static char[] _lib;

 4

dotnet程式優化心得(三)

    static int _size;

 5

dotnet程式優化心得(三)

 6

dotnet程式優化心得(三)

    static QuickChineseConvert()

 7

dotnet程式優化心得(三)

    {

 8

dotnet程式優化心得(三)

        _size=UInt16.MaxValue;

 9

dotnet程式優化心得(三)

        Init();

10

dotnet程式優化心得(三)

    }

11

dotnet程式優化心得(三)

    static string GB_lib="……";

12

dotnet程式優化心得(三)

    static string BIG5_lib="……";

13

dotnet程式優化心得(三)

14

dotnet程式優化心得(三)

    private static void PushIntoArray(char[] c , string g, string b)

15

dotnet程式優化心得(三)

16

dotnet程式優化心得(三)

        for (int i=0;i<g.Length;i++)

17

dotnet程式優化心得(三)

        {

18

dotnet程式優化心得(三)

            c[Convert.ToUInt16(g[i])]=b[i];

19

dotnet程式優化心得(三)

        }

20

dotnet程式優化心得(三)

21

dotnet程式優化心得(三)

22

dotnet程式優化心得(三)

    private static void Init()

23

dotnet程式優化心得(三)

24

dotnet程式優化心得(三)

        _lib = new char[_size];

25

dotnet程式優化心得(三)

        PushIntoArray(_lib,GB_lib,BIG5_lib);

26

dotnet程式優化心得(三)

27

dotnet程式優化心得(三)

28

dotnet程式優化心得(三)

    public static char ToBIG5(char inputChar)

29

dotnet程式優化心得(三)

30

dotnet程式優化心得(三)

        char temp = _lib[Convert.ToUInt16(inputChar)];

31

dotnet程式優化心得(三)

        return temp==0?inputChar:(char)temp;

32

dotnet程式優化心得(三)

33

dotnet程式優化心得(三)

34

dotnet程式優化心得(三)

    public static string ToBIG5(string inputString)

35

dotnet程式優化心得(三)

36

dotnet程式優化心得(三)

        StringBuilder sb = new StringBuilder();

37

dotnet程式優化心得(三)

        for (int i=0;i<inputString.Length;i++)

38

dotnet程式優化心得(三)

39

dotnet程式優化心得(三)

            sb.Append(ToBIG5(inputString[i]));

40

dotnet程式優化心得(三)

41

dotnet程式優化心得(三)

        return sb.ToString();

42

dotnet程式優化心得(三)

43

dotnet程式優化心得(三)

}

這樣的話,對于每一個字元,隻進行幾個簡單的操作了:

Convert.ToUInt16(inputChar)

從數組中取值_lib[Convert.ToUInt16(inputChar)]

然後就是return temp==0?inputChar:(char)temp;

對比Hashtable臭長臭長的get_Item(object key),這下簡單多了!當然,要付出一定代價,代價就是要弄一個大小為UInt16.MaxValue的數組,不大嘛。

測試性能,很鼓舞人心:1857萬字/s

(5)Go on...........

還能繼續優化嗎?數組不是還要檢查邊界條件嗎?用指針?書上說能提高性能17%。17%少了點,不過也試一試。測試結果表明,性能沒怎麼提高。現在性能瓶頸在傳值,return那一塊,用ref,out什麼的試一試?

做了以下類似的改動,這個性能又提了到差不多10倍。

1

dotnet程式優化心得(三)

                public static void ToBIG5(ref char inputChar)

2

dotnet程式優化心得(三)

                {

3

dotnet程式優化心得(三)

                        char temp = LibGB2BIG5[Convert.ToUInt16(inputChar)];

4

dotnet程式優化心得(三)

                        if (temp!=0) inputChar=temp;

5

dotnet程式優化心得(三)

                }

dotnet程式優化心得(三)

                public static void ToBIG5(ref char[] inputString)

dotnet程式優化心得(三)
dotnet程式優化心得(三)

                        for (int i=0;i<inputString.Length;i++)

dotnet程式優化心得(三)

                        {

dotnet程式優化心得(三)

                                inputString[i]=ToBIG5(inputString[i]);

6

dotnet程式優化心得(三)

                        }

7

dotnet程式優化心得(三)

測試結果:1.444億字/s。10個指令周期一個字元!!應該不能再優化了吧!到此為止吧,這性能應該夠用了.

不過這個結果有點僞,因為必須傳入字元或字元數組。而String是隻讀的,使用過程必須複制一遍,用String做參數性能隻到的了8000萬字/s左右

(6)優化路徑小結

            簡單的方法,Replace,30萬字/s 

------->采用更好的資料結構和算法(Hashtable),300萬字/s

------->用reflector檢視Hashtable代碼,做進一步的優化,500萬字/s

------->分析問題所在,直接采用數組,用空間換取時間,1850萬字/s

------->采用ref,out等技巧做進一步優化,1.44億字/s(傳數組)8000萬字/s(傳string)

本文轉自xiaootie部落格園部落格,原文連結http://www.cnblogs.com/xiaotie/archive/2005/08/15/215261.html如需轉載請自行聯系原作者

xiaotie 集異璧實驗室(GEBLAB)

繼續閱讀