每次我的对象被创建(几次),我拿这三个文件,并使用JsonConvert.DeserializeObject来反序列化数组到对象.
我想到使用二进制文件而不是json-string,甚至可以直接保存这些数组?我不需要使用这些文件,它只是数据当前保存的位置.我会乐意切换到更快的东西.
加速这些对象的初始化有什么不同的方法?
解决方法
一个简单的方法是创建一个FileStream,然后将其包装在一个二进制文件/二进制阅读器中.
您可以访问函数来编写基本数据结构(数字,字符串,字符,字节[]和字符[]).
一个简单的方法来编写一个int [](如果它是固定的大小),这是通过使用int / long的前缀长度来取代数组(取决于大小,unsigned并不能给出任何优势,因为数组使用带符号的数据类型长度存储).然后写所有的ints.
写入所有内容的两种方式是:
简单地循环整个阵列.
2.将其转换为字节[],并使用BinaryWriter.Write(byte [])写入
这些是如何实现它们:
// 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仅在我的系统上平均消耗了568600ns(平均为0.57ms).
方法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.我希望这能给你一些处理非常大的数据文件的洞察力:).