我正在使用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;
由于未设置或设置为默认值的属性不会占用任何内存,因此我倾向于认为展平的架构可能不是问题。但我不确定。
(请注意,性能是我主要关注的问题,紧接着是内存使用情况。规范化架构表现非常出色,但我认为扁平化架构确实可以帮助我清理代码库。)
答案 0 :(得分:1)
基础知识首先要明确:
每个表的顶部都有一个vtable,它表示可以找到表的每个字段的偏移量。如果表格中的字段太多,无论您是否存储数据,此vtable都会变得庞大。
如果您尝试创建表层次结构,则会创建额外的vtable,并为设计添加间接成本。
如果在多个对象中存储了类似的数据,也会共享vtables。就像创建只使用exif_camera变量的对象一样!
因此,这取决于您的数据是否会变得庞大且异构使用更有组织的层次结构。但是如果你的数据是同质的,那就更喜欢扁平的桌子了。
答案 1 :(得分:0)
由于您的大多数数据都是字符串,因此这两种设计的大小和速度都非常相似,因此您应该根据软件工程角度更适合您的选择。
也就是说,平面版本的大小可能略微更高效(vtable更少),访问速度肯定会更快(尽管这主要是字符串数据,因此这种情况很少)。
平面版本效率较低的唯一方法是,如果要将大量文件存储在一个缓冲区中,其中设置的字段在每个表之间变化很大。然后非平面版本可以生成更多vtable共享。
在非平面版本中,GPSProperties
这样的表格可能是struct
,如果这些字段不太可能发生变化,效率会更高。
答案 2 :(得分:0)
这个单个表可能有几百个字段,但大多数都可以 是空的。
性能成本可能很小,你不会注意到,但对我来说,你的上述引用是影响使用哪种设计的摇摆因素。
其他人在谈论vtable的成本;我根本不担心这一点。每个班级有一个单独的vtable,每次运行准备一次并且不会很贵。 拥有100个空的字符串并且未使用它将会非常昂贵(明智地使用内存)并且会消耗你创建的每个对象;另外,阅读你的字段将变得更加复杂,因为你不能再认为你读过的所有数据都在那里。
如果大多数/所有领域都在那里,那么我可以看到制作单一课程的吸引力;但他们不是。