更好/更快的方式填补一个大数组在C#
我有3 * .dat文件(346KB,725KB,1762KB),填充有一个“大”int数组的json字符串.
每次我的对象被创建(几次),我拿这三个文件,并使用JsonConvert.DeserializeObject来反序列化数组到对象. 我想到使用二进制文件而不是json-string,甚至可以直接保存这些数组?我不需要使用这些文件,它只是数据当前保存的位置.我会乐意切换到更快的东西. 加速这些对象的初始化有什么不同的方法? 解决方法
最快的方法是手动序列化数据.
一个简单的方法是创建一个FileStream,然后将其包装在一个二进制文件/二进制阅读器中. 您可以访问函数来编写基本数据结构(数字,字符串,字符,字节[]和字符[]). 一个简单的方法来编写一个int [](如果它是固定的大小),这是通过使用int / long的前缀长度来取代数组(取决于大小,unsigned并不能给出任何优势,因为数组使用带符号的数据类型长度存储).然后写所有的ints. 写入所有内容的两种方式是: 这些是如何实现它们: // Writing BinaryWriter writer = new BinaryWriter(new FileStream(...)); int[] intArr = new int[1000]; writer.Write(intArr.Length); for (int i = 0; i < intArr.Length; i++) writer.Write(intArr[i]); // Reading BinaryReader reader = new BinaryReader(new FileStream(...)); int[] intArr = new int[reader.ReadInt32()]; for (int i = 0; i < intArr.Length; i++) intArr[i] = reader.ReadInt32(); // Writing,method 2 BinaryWriter writer = new BinaryWriter(new FileStream(...)); int[] intArr = new int[1000]; byte[] byteArr = new byte[intArr.Length * sizeof(int)]; Buffer.BlockCopy(intArr,byteArr,intArr.Length * sizeof(int)); writer.Write(intArr.Length); writer.Write(byteArr); // Reading,method 2 BinaryReader reader = new BinaryReader(new FileStream(...)); int[] intArr = new int[reader.ReadInt32()]; byte[] byteArr = reader.ReadBytes(intArr.Length * sizeof(int)); Buffer.BlockCopy(byteArr,intArr,byteArr.Length); 我决定把这全部放在测试中,用10000个整数的数组,我经过10000次测试. 这导致方法在我的系统上平均消耗888200ns(约0.89ms). 这两次都包括垃圾收集器所要做的工作. 显然方法2比方法1更快,尽管可读性更差. 方法1可以比方法2更好的另一个原因是因为方法2需要比您要编写的数据(原始int []和从[int]]转换的字节[]的两倍)当处理有限的RAM /超大文件(大约512MB)时,尽管如此,您可以随时制作混合解决方案,例如一次写入128MB. 请注意,方法1还需要这个额外的空间,但是因为它在int []的每个项目中被分解为1个操作,所以它可以更早地释放内存. 这样的东西,一次会写128MB的int []: const int WRITECOUNT = 32 * 1024 * 1024; // 32 * sizeof(int)MB int[] intArr = new int[140 * 1024 * 1024]; // 140 * sizeof(int)MB for (int i = 0; i < intArr.Length; i++) intArr[i] = i; byte[] byteArr = new byte[WRITECOUNT * sizeof(int)]; // 128MB int dataDone = 0; using (Stream fileStream = new FileStream("data.dat",FileMode.Create)) using (BinaryWriter writer = new BinaryWriter(fileStream)) { while (dataDone < intArr.Length) { int dataToWrite = intArr.Length - dataDone; if (dataToWrite > WRITECOUNT) dataToWrite = WRITECOUNT; Buffer.BlockCopy(intArr,dataDone,dataToWrite * sizeof(int)); writer.Write(byteArr); dataDone += dataToWrite; } } 请注意,这只是为了写作,阅读工作也不同:P.我希望这能给你一些处理非常大的数据文件的洞察力:). (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |