C# 在C中填充大数组的更好/更快的方法#

C# 在C中填充大数组的更好/更快的方法#,c#,arrays,initialization,C#,Arrays,Initialization,我有3个*.dat文件(346KB、725KB、1762KB),其中填充了一个json字符串“big”int数组 每次创建对象时(多次),我都会获取这三个文件,并使用JsonConvert.DeserializeObject将数组反序列化到对象中 我考虑过使用二进制文件而不是json字符串,或者我甚至可以直接保存这些数组?我不需要使用这些文件,它只是数据当前保存的位置。我很乐意换成更快的 加快这些对象初始化的不同方法有哪些?如果您只得到一组整数,那么使用JSON在解析方面确实会非常低效。您可以使

我有3个*.dat文件(346KB、725KB、1762KB),其中填充了一个json字符串“big”int数组

每次创建对象时(多次),我都会获取这三个文件,并使用
JsonConvert.DeserializeObject
将数组反序列化到对象中

我考虑过使用二进制文件而不是json字符串,或者我甚至可以直接保存这些数组?我不需要使用这些文件,它只是数据当前保存的位置。我很乐意换成更快的


加快这些对象初始化的不同方法有哪些?

如果您只得到一组整数,那么使用JSON在解析方面确实会非常低效。您可以使用
BinaryReader
BinaryWriter
高效地编写二进制文件。。。但我不清楚为什么每次创建对象时都需要读取文件。为什么每个新对象都不能保留对原始数组的引用,而原始数组已经被读取过一次?或者,如果他们需要修改数据,您可以保留一个“规范源”,每次创建对象时只需在内存中复制该数组。

从整数数组创建字节数组的最快方法是使用Buffer.BlockCopy

byte[] result = new byte[a.Length * sizeof(int)];
Buffer.BlockCopy(a, 0, result, 0, result.Length);
// write result to FileStream or wherever
如果将数组的大小存储在第一个元素中,则可以再次使用它进行反序列化。确保所有内容都能放入内存,但根据您的文件大小,它应该是合适的

var buffer = File.ReadAllBytes(@"...");
int size = BitConverter.ToInt32(buffer,0);
var result = new int[size];
Buffer.BlockCopy(buffer, 0, result, result.length);

二进制不是人类可读的,但肯定比JSON快。

最快的方法是手动序列化数据

一种简单的方法是创建一个文件流,然后将其包装到BinaryWriter/BinaryReader中

您可以访问函数来编写基本数据结构(
numbers
string
char
byte[]
char[]

编写
int[]
的一种简单方法(如果数组的大小是固定的,则不需要这样做)是使用int/long(取决于大小,unsigned实际上没有任何优势,因为数组使用带符号的数据类型存储其长度)。然后写下所有的整数

写入所有int的两种方法是:
1.只需在整个阵列上循环。
2.将其转换为
byte[]
并使用
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, 0, byteArr, 0, 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, 0, intArr, 0, byteArr.Length);
请注意,这只是为了写作,阅读的效果也不一样。
我希望这能让您在处理非常大的数据文件时有更多的见解:)。

我不太清楚您的要求是什么-您能否向我们展示您现有的代码,然后我们可以尝试解决如何改进它?数据是如何准确存储的?每个数组一行?+1表示“为什么每个新对象不能保留对原始数组的引用”
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, byteArr, 0, dataToWrite * sizeof(int));
        writer.Write(byteArr);
        dataDone += dataToWrite;
    }
}