首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用Protobuf存储二维阵列(C#)

问用Protobuf存储二维阵列(C#)
EN

Stack Overflow用户
提问于 2021-01-24 09:49:02
回答 2查看 453关注 0票数 1

我有一个大型的多维数组,需要用protobuf存储。数组中最多可以有5120*5120 = 26,214,400项。不幸的是,Protobuf不支持存储多维数组。

作为测试,我编写了两个函数和一个额外的类。类存储和x,y,它指向数组中的位置(arrayx,y)。这个类有一个“值”,它是来自arrayx,y的数据。我使用一个列表来存储这些数据。

当我生成一个相当小的数组(1024*1024)时,我会得到一个超过169 is的输出文件。从我的测试中,它以极快的速度加载和生成文件,因此没有问题。然而,文件的大小是巨大的-我肯定需要削减的大小。

这是一个正常的文件大小,还是我要重新考虑我的整个过程?我是否应该在保存数据之前压缩它(压缩文件将它从169 6MB压缩到6MB)?如果是这样,在C#中压缩文件的最快/最简单方法是什么?

这是基于我真实代码的伪代码。

代码语言:javascript
复制
[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。

我很感谢你的建议。

EN

回答 2

Stack Overflow用户

发布于 2021-01-24 10:26:56

我不知道储藏室的事,但这可能不是正确的方法。

按照您的做法,您正在为数组中的每个单元格创建一个MultiArray对象。

一个更简单和更有效的解决办法是这样做:

代码语言:javascript
复制
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];
    }
}  
票数 2
EN

Stack Overflow用户

发布于 2021-01-24 11:55:25

最终,protobuf格式没有一个高维度数组的概念。

在库级,由于您使用的是protobuf,所以我们可以让库在这里做一些魔术,本质上是把它当作;

代码语言:javascript
复制
message Array_T {
    repeated int32 dimensions;
    repeated T items; // packed when possible
}

(注意到.proto实际上并不支持泛型,但这在库级别并不重要)

然而,从x-plat的角度来看,这可能有点尴尬。

但是要测试这是否有用,你可以线性化你的二维数组,看看它需要多少空间。

在您的例子中,我怀疑真正的问题(即大小)是字符串的数量。Protobuf每次都写入字符串内容,而不尝试查找表。也可能值得检查数组内容的字符串长度(以UTF-8字节为单位)的sunlm总数。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65869115

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档