【问题标题】:Is there an off the shelf binary format that allows string caching是否有现成的二进制格式允许字符串缓存
【发布时间】:2016-01-24 12:14:55
【问题描述】:

我正在研究将高度自定义且高效的二进制格式迁移到一种可用的二进制格式。数据存储在其他地方的一些低功率移动设备上,因此性能是重要的要求。 当前格式的优点是所有字符串都存储在一个池中。这意味着我们不会在文件中重复相同的字符串数百次,我们在反序列化期间只读取一次,并且所有对象都通过其索引引用它。这也意味着我们在内存中只保留一份副本。所以有很多优点:) 我无法为 capnproto 或 flatbuffers 找到支持这一点的方法。或者我需要在顶部构建层,并在生成的对象中显式使用整数索引来字符串?

谢谢!

【问题讨论】:

  • 为什么问题被否决了?正如我们所见,他们的手册中对此没有明确的信息。

标签: binaryfiles flatbuffers capnproto


【解决方案1】:

FlatBuffers 支持字符串池。只需序列化一个字符串一次,然后在其他对象中多次引用该字符串。字符串只会在内存中出现一次。

最简单的例子,架构:

table MyObject { name: string; id: string; }

代码(C++):

FlatBufferBuilder fbb;
auto s = fbb.CreateString("MyPooledString");
// Both string fields point to the same data:
auto o = CreateMyObject(fbb, s, s);
fbb.Finish(o);

【讨论】:

  • 我是否错过了他们文档中的相关信息?
  • 它隐含在“内部”部分,但可能更清楚,是的。
  • @Aardappel 我猜 Flatbuffers 不防御amplification attacks
  • @kenton-varda :确实如此。它有一个验证器,您可以在其中指定仍然合法的最大访问对象。它不允许设计周期(无符号偏移)。
  • 嗯,所以基本上你需要估计一个对象可能被重用多少次,而不是依靠消息的总大小来估计它包含多少数据。我想这有点道理。
【解决方案2】:

您总是可以手动执行此操作,例如:

struct MyMessage {
  stringTable @0 :List(Text);

  # Now encode string fields as integer indexes into the string table.
  someString @1 :UInt32;
  otherString @2 :UInt32;
}

Cap'n Proto 理论上可以允许多个指针指向同一个对象,但出于安全原因目前禁止这样做:通过发送循环或包含的消息来拒绝不期望它的服务器太容易了很多重叠的参考。 See the section on amplification attacks in the docs.

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-16
    • 2023-03-11
    • 1970-01-01
    • 2020-01-05
    相关资源
    最近更新 更多