我有一个大型的多维数组,需要用protobuf存储。数组中最多可以有5120*5120 = 26,214,400项。不幸的是,Protobuf不支持存储多维数组。
作为测试,我编写了两个函数和一个额外的类。类存储和x,y,它指向数组中的位置(arrayx,y)。这个类有一个“值”,它是来自arrayx,y的数据。我使用一个列表来存储这些数据。
当我生成一个相当小的数组(1024*1024)时,我会得到一个超过169 is的输出文件。从我的测试中,它以极快的速度加载和生成文件,因此没有问题。然而,文件的大小是巨大的-我肯定需要削减的大小。
这是一个正常的文件大小,还是我要重新考虑我的整个过程?我是否应该在保存数据之前压缩它(压缩文件将它从169 6MB压缩到6MB)?如果是这样,在C#中压缩文件的最快/最简单方法是什么?
这是基于我真实代码的伪代码。
[ProtoContract]
public class Example
{
[ProtoIgnore]
public string[,] MyArray { get; set; }
[ProtoMember(0)]
private List<MultiArray> Storage { get; set; }
public void MoveToList()
{
for (int x = 0; x < MyArray.GetLength(0); x++)
{
for (int y = 0; y < MyArray.GetLength(1); y++)
{
Storage.Add(new MultiArray
{
_x = x,
_y = y,
value = MyArray[x, y]
});
}
}
}
public void MoveToArray()
{
MyArray = new string[1024, 1024];
for (int i = 0; i < Storage.Count; i++)
{
MyArray[Storage[i].X, Storage[i].Y] = Storage[i]._value;
}
}
}
[ProtoContract]
public class MultiArray
{
[ProtoMember(0)]
public int _y { get; set; }
[ProtoMember(1)]
public int _x { get; set; }
[ProtoMember(2)]
public string _value { get; set; }
}注意:该值必须是数组的正确x/y。
我很感谢你的建议。
发布于 2021-01-24 10:26:56
我不知道储藏室的事,但这可能不是正确的方法。
按照您的做法,您正在为数组中的每个单元格创建一个MultiArray对象。
一个更简单和更有效的解决办法是这样做:
String[] Storage = new String[1024*1024];
int width = 1024
int height = 1024;
for (int x = 0; x < width; x++)
{
for (int y = 0; y < height; y++)
{
Storage[x*width+y]=MyArray[x,y];
}
} 发布于 2021-01-24 11:55:25
最终,protobuf格式没有一个高维度数组的概念。
在库级,由于您使用的是protobuf,所以我们可以让库在这里做一些魔术,本质上是把它当作;
message Array_T {
repeated int32 dimensions;
repeated T items; // packed when possible
}(注意到.proto实际上并不支持泛型,但这在库级别并不重要)
然而,从x-plat的角度来看,这可能有点尴尬。
但是要测试这是否有用,你可以线性化你的二维数组,看看它需要多少空间。
在您的例子中,我怀疑真正的问题(即大小)是字符串的数量。Protobuf每次都写入字符串内容,而不尝试查找表。也可能值得检查数组内容的字符串长度(以UTF-8字节为单位)的sunlm总数。
https://stackoverflow.com/questions/65869115
复制相似问题