代码改变世界

小问题 看性能 之 学习随机方法

2009-05-12 14:25  JiWin  阅读(130)  评论(0)    收藏  举报

问题:一个int数组,长度为1000,并向其中随机插入1-1000之间的数字,并且数字不能重复。

原题基本是这样,可能还有其他长度的版本题目。无所谓了,为了能比较细致体现出性能的差别,长度还可以扩大些。

关键代码如下:

...

//使用Stopwacth进行统计开销

 Stopwatch sw = new Stopwatch();
sw.Start();
            const int Max = 1000;
            Random rm = new Random(0);

//最终完成要求的数组
            int[] aryTmp = new int[Max];

//装载初始值的数组
            int[] resTmp = new int[Max];
            for (int i = 0; i < Max; i++)
                resTmp[i] = i + 1;

//循环把resTmp 数组中的数,填充到aryTmp数组中

//随机性在resTmp 中索引的位置上产生

int t= 0;

for (int num = 0; num < Max; num++)
            {
                t = rm.Next(resTmp.Length - num);
                aryTmp[num] = resTmp[t];
                resTmp[t] = resTmp[resTmp.Length - num - 1];
            }

//输出代码的开销(tick)
Console.WriteLine("Time(tick):" + sw.ElapsedTicks);
            sw.Stop();

...

 

具体输出和硬件环境及运行环境有很大的关系。所以在这里我就不写输出的结果了,在统计中我是用10次的运行结果的平均值,峰值及谷值作为最终结果。

之上的代码在网上有人也提到了,我认为这个方法不错,省去了判断的过程。我想在这个过程中是否能再进一步提高性能呢?

上述方式的问题出现在:

a)开销一个副本数组

b)rm.Next()方法的调用耗时

 

通过上述问题,我的思考出发点就明确了 1)避免使用副本数组 2)减少Next()方法的调用

最初思路是:以1000长度为例,我只取其中的前500数组去装数值 ,另外500个由调用Next()方法产生随机数,并通过映射关系映射到后500数组

《未完成待续》