首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >FlatBuffers存储/大小保证

FlatBuffers存储/大小保证
EN

Stack Overflow用户
提问于 2019-05-20 04:52:08
回答 1查看 941关注 0票数 1

FlatBuffers特别避免了某些编码标准化/保证。根据文件:

(internals.html)

这可能意味着,如果输入值相同,两个不同的实现可能产生不同的二进制文件,这是完全有效的。

好的,但是在磁盘上编码的字符串是直接从给出的任何表示还是在其他表示中编码的吗?使用相同的FlatBuffers版本和生成的代码是否具有确定性(参数相同的N个操作产生相同的结果)?

尺寸如何?动态结构的尺寸减小(例如向量,使字符串值变短)是否会相应地缩小编码结构的大小?

我真的不明白字符串编码是如何工作的,我现在也没有时间分解内部代码。

我创建了一个具有普通父->子->外孙结构的示例定义,其中父类型具有子类型的向量,而外孙类型嵌入字符串和结构。我想夸大不同类型的值可能带来的任何熵,包括其中的几个。然后,我用一个5符文字符串乘以50,在孙辈中填充了字符串值,然后用手迭代地将乘法器减为1,每次打印最终编码的输出大小:

代码语言:javascript
复制
$ go run main.go
String size: (250)
Output encoding size: (400)

$ go run main.go
String size: (245)
Output encoding size: (400)

$ go run main.go
String size: (240)
Output encoding size: (392)

$ go run main.go
String size: (235)
Output encoding size: (384)

为什么在我从原始字符串值中删除5个字节后,编码的输出大小没有改变?为什么从原来的字符串中每下降5个字节,它就会收缩8个字节?因为这些都是字符串,所以我不认为对齐会在这里发挥作用。

我还有上面的问题,但似乎是一个安全的假设(呃,保证),一)对于相同的参数,编码的大小是稳定的,二)随着其中一个或多个值的减小而缩小。这是真实的说法吗?

谢谢你为我节省了一些时间和错误,因为我现在不需要自己破解了(希望如此)。

以下是供参考的定义:

代码语言:javascript
复制
namespace testformat;

struct Vector {
    field9:ulong;
    field10:ulong;
    field11:ulong;
}

table Grandchild {
    field5:ulong;
    string6:string;
    field7:ulong;
    field8:Vector;
}

table Child {
    field3:ulong;
    field4:ulong;
    grandchild:Grandchild;
}

table Parent {
    field1:ulong;
    field2:ulong;
    children:[Child];
}

root_type Parent;

这是具有重复字符串值的Go代码的一部分,我更改了这个值(在顶部):

代码语言:javascript
复制
stringValue := strings.Repeat("strin", 50)
fmt.Printf("String size: (%d)\n", len(stringValue))

stringOffset := b.CreateString(stringValue)

testformat.GrandchildStart(b)

testformat.GrandchildAddField5(b, 44)
testformat.GrandchildAddString6(b, stringOffset)
testformat.GrandchildAddField7(b, 55)

vectorOffset := testformat.CreateVector(b, 11, 22, 33)
testformat.GrandchildAddField8(b, vectorOffset)

grandchildOffset := testformat.GrandchildEnd(b)
EN

回答 1

Stack Overflow用户

发布于 2019-05-20 18:54:17

这包含了许多问题,下面是一些答案:

  • 字符串: FlatBuffers将这些数据存储为UTF-8,因此在输入已经可以为UTF-8的语言中(通常在C++中),序列化这些数据是一个没有任何处理的直接副本。在使用其他表示形式(如Java)的语言中,序列化时有一个转换步骤。
  • 调整大小:是的,减小矢量的大小通常会减少缓冲区的大小,但不一定是相等的。例如,如果您有一个简短向量,则根据对齐情况,将缓冲区大小减少1元素可能会使缓冲区减少0或4。
  • 在你的实验中,你再次看到了对齐和填充的效果。所有的东西都按照自己的大小对齐(几乎所有编程语言都将数据存储在内存中)。因此,如果缓冲区包含doublelong或其他任何东西,缓冲区的大小只会以8字节递增。字符串的大小是4字节对齐的,但实际的字符串数据只有1字节对齐,因此可以在不改变缓冲区大小的情况下向字符串中添加字符,因为它只是使用以前填充字节的更多内容。即使字符串字节不需要对齐,相邻的数据也可能。
  • 1:只有在顺序相同或语言/实现相同的情况下。有些实现可能更改顺序,从而影响对齐和填充。
  • 2:正如我上面所指出的,缓冲大小的减少只是间接地与元素的减少有关。
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56214479

复制
相关文章

相似问题

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