使用更平坦的架构的性能影响

时间:2018-06-07 13:31:03

标签: c++ flatbuffers

我正在使用FlatBuffers(C ++)来存储有关文件的元数据信息。这包括EXIF,IPTC,GPS和各种其他元数据值。

在我当前的架构中,我有一个相当规范化的定义,其中上面列出的每个组都有自己的表。根表只包含每个子表的属性。

基本示例:

table GPSProperties {
  latitude:double;
  longitude:double;
}

table ContactProperties {
  name:string;
  email:string;
}

table EXIFProperties {
  camera:string;
  lens:string;
  gps:GPSProperties;
}

table IPTCProperties {
  city:string;
  country:string;
  contact:ContactProperties;
}

table Registry {
 exifProperties:EXIFProperties;
 iptcProperties:IPTCProperties;
}

root_type Registry;

这样可行,但构建缓冲区时的嵌套限制开始使代码变得非常混乱。同样,将属性分解为单独的表仅用于模式中的清晰度。

我正在考虑将整个架构“扁平化”为单个表格,但我想知道这样做是否存在任何性能或内存影响。这个单个表可以有几百个字段,但大多数都是空的。

提案:

table Registry {
  exif_camera:string;
  exif_lens:string;
  exif_gps_latitude:double;
  exif_gps_longitude:double;
  iptc_city:string;
  iptc_country:string;
  iptc_contact_name:string;
  iptc_contact_email:string;
}

root_type Registry;

由于未设置或设置为默认值的属性不会占用任何内存,因此我倾向于认为展平的架构可能不是问题。但我不确定。

(请注意,性能是我主要关注的问题,紧接着是内存使用情况。规范化架构表现非常出色,但我认为扁平化架构确实可以帮助我清理代码库。)

3 个答案:

答案 0 :(得分:1)

基础知识首先要明确:

  1. 每个表的顶部都有一个vtable,它表示可以找到表的每个字段的偏移量。如果表格中的字段太多,无论您是否存储数据,此vtable都会变得庞大。

  2. 如果您尝试创建表层次结构,则会创建额外的vtable,并为设计添加间接成本。

  3. 如果在多个对象中存储了类似的数据,也会共享vtables。就像创建只使用exif_camera变量的对象一样!

  4. 因此,这取决于您的数据是否会变得庞大且异构使用更有组织的层次结构。但是如果你的数据是同质的,那就更喜欢扁平的桌子了。

答案 1 :(得分:0)

由于您的大多数数据都是字符串,因此这两种设计的大小和速度都非常相似,因此您应该根据软件工程角度更适合您的选择。

也就是说,平面版本的大小可能略微更高效(vtable更少),访问速度肯定会更快(尽管这主要是字符串数据,因此这种情况很少)。

平面版本效率较低的唯一方法是,如果要将大量文件存储在一个缓冲区中,其中设置的字段在每个表之间变化很大。然后非平面版本可以生成更多vtable共享。

在非平面版本中,GPSProperties这样的表格可能是struct,如果这些字段不太可能发生变化,效率会更高。

答案 2 :(得分:0)

  

这个单个表可能有几百个字段,但大多数都可以   是空的。

性能成本可能很小,你不会注意到,但对我来说,你的上述引用是影响使用哪种设计的摇摆因素。

其他人在谈论vtable的成本;我根本不担心这一点。每个班级有一个单独的vtable,每次运行准备一次并且不会很贵。  拥有100个空的字符串并且未使用它将会非常昂贵(明智地使用内存)并且会消耗你创建的每个对象;另外,阅读你的字段将变得更加复杂,因为你不能再认为你读过的所有数据都在那里。

如果大多数/所有领域都在那里,那么我可以看到制作单一课程的吸引力;但他们不是。