天天看点

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)

继续阅读