优化模拟的flatbuffer字典

时间:2017-11-20 09:43:55

标签: c++ flatbuffers

我的flatbuffers架构文件dict.fbs如下所示:

namespace fbs;

table Dict {
    entries:[DictEntry];
}

table DictEntry {
    key:string (key);
    value:string;
}

root_type Dict;

现在根据文档,你可以在Flatbuffers中模拟一个带有排序向量和二进制查找的字典

flatbuffers::FlatBufferBuilder builder(1024);

std::string key, value; 
std::ifstream infile(argv[1]);
std::string outfile(argv[2]);

std::vector<flatbuffers::Offset<DictEntry>> entries;

while (std::getline(infile, key) && std::getline(infile, value)) {
    entries.push_back(CreateDictEntryDirect(builder, key.c_str(), value.c_str()));
}

auto vec = builder.CreateVectorOfSortedTables(&entries);
auto dict = CreateDict(builder, vec);

builder.Finish(dict);

我的原始单词列表在磁盘上有32MB。现在,对于此列表中的每个单词,我都有一个标准化的key和一个相应的value。如果序列化的flatbuffer dict现在的大小是磁盘的两倍,比如64MB,那将是合乎逻辑的,但实际上输出为111MB

我可以优化此架构以使其更紧凑吗?是什么让输出量几乎达到了4倍?

1 个答案:

答案 0 :(得分:1)

字符串相对较小吗?平均长度是多少?

您的头顶将是:2个字符串,每个字符串具有32位长度字段,以及可能的填充。然后每个DictEntry有12个字节(vtable offset + 2个字符串偏移)。然后另一个32位偏移到向量中的偏移量。所以,是的,如果字符串很小,可能会增加很多。

请注意,如果您使用的是std::map<std::string, std::string>,那么您最终可能会使用更多内存。

我建议你尝试使用FlexBuffers(https://google.github.io/flatbuffers/flexbuffers.html)做同样的事情,它有一个更紧凑的字符串表示,并且为了你的目的应该是相同的速度(因为你的数据是&#34;字符串键入&#34 ;无论如何)。