首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

亿级数据时,内存储器性能低于IO性能

2013-10-12 
亿级数据时,内存性能低于IO性能最近因项目需要,需要生成有0到99999999共1亿的不重复数,于是想着直接将这些

亿级数据时,内存性能低于IO性能

最近因项目需要,需要生成有0到99999999共1亿的不重复数,于是想着直接将这些数据生成为一个文件就可以了,代码如。

private void mergeMultiFileStream(string savePath,                                     FileStream[] streams,                                     int dataBlockLength = 8)        {            FileStream destStream = new FileStream(savePath, FileMode.Create, FileAccess.ReadWrite, FileShare.None);            for (int index = 0; index < streams.Length; index++)            {                int streamIndex = index;                               FileStream stream = streams[streamIndex];                stream.Position = 0;                byte[] tempCodeBytes = new byte[stream.Length];                stream.Read(tempCodeBytes, 0, tempCodeBytes.Length);                tempCodeBytes = randomData(tempCodeBytes, dataBlockLength);                destStream.Write(tempCodeBytes, 0, tempCodeBytes.Length);                stream.Close();                        }            destStream.Close();        }private byte[] randomData(byte[] sourceData, int randomDataBlockLength)        {            List<byte[]> tempData = new List<byte[]>();            for (int index = 0; index < sourceData.Length; index += randomDataBlockLength)            {                int dataLength = randomDataBlockLength;                if (sourceData.Length - index < randomDataBlockLength)                {                    dataLength = sourceData.Length - index;                }                byte[] tempDataBlock = new byte[dataLength];                Array.Copy(sourceData, index, tempDataBlock, 0, dataLength);                tempData.Add(tempDataBlock);            }            byte[] newData = new byte[sourceData.Length];            int newDataCopyBeginIndex = 0;            while (tempData.Count > 0)            {                int index = generateRandomInt(0, tempData.Count);                byte[] tempDataBlock = tempData[index];                Array.Copy(tempDataBlock, 0, newData, newDataCopyBeginIndex, tempDataBlock.Length);                newDataCopyBeginIndex += tempDataBlock.Length;                tempData.RemoveAt(index);            }            tempData.Clear();            return newData;        }
这里要注意的是,为了确保randomData函数中所用的List能释放,增加了tempData.Clear()的处理,以清空List,从而避免因垃圾回收不够及时,而导致内存占用过多的情况。

这样一样,程序再次跑了起来,得到的数据已经随机了。如果还要进一步随机,可以将生成后的文件,再次读取分成多个文件(如10000),再随机处理合并。

达到了目的之后,就想着怎么去优化,能不能在更短的时间里去处理完数据,于是想到了多线程。但是当我将多线程加进去处理后,发现并不能达到太理想的效果,因为CPU和内存的占用又一次居高不下,电脑又一次卡死。

这是怎么回事?

分析了一番之后,得出这样的结论,一般情况下,若是采用多线程处理,确实可以加快速度。但是由于这里的数据量太大,需要开多一点的线程来处理数据,才能提升速度,但是当分成多个线程处理时,虽然单位时间内多个线程可以并行处理数据,但这样一样,每个线程都会消耗内存,都要CPU处理,所以线程一多,内存消耗就会变大,CPU的占用也就会变高。

可能是我当时开了太多线程导致了这样的结果,或许开少一占的线程,比如5个或者10个,但这样一来,又需要协调好文件数量的分配,让每个线程处理若干个文件,而为了协调好这些,需要有自增操作(文件流数组索引是逐个递增的),而在多线程中的自增操作,必须采用原子性的增加(Interlock.Increacement),否则会出现自增时的竞争,从而导到意外的结果。比如A线程要用某个流时,因流数据索引的错位,导致B线程也使用到了同一个流,而B线程又快于A线程处理完数据,结果 流被关闭,A线程无法操作。即便随开了流的关闭,但A线程和B线程引用了同样的流,这样的数据就会出现重复,无法满足项目要求。

所以最终,为了确保数据的准确性,没有采用多线程来处理。

从这里也看出另一点,虽然使用内存来处理数据比IO处理数据时更快,但是由于内存大小的局限,当数据量达到一定量级时,内存就会捉襟见肘,这时不可避免的要使用磁盘来转存数据,以分担内存的消耗。所以在亿级数据时,如果全部采用内存来处理,其性能并不会高于IO操作的性能。

转载请注明出处http://blog.csdn.net/xxdddail/article/details/12645957


热点排行