Tag: Bson

我们如何解析BSON不会产生开销性能

BSON是一个鲜为人知的图书馆,经常使用。 它是MongoKitten的核心,并且BSON规范一直被所有MongoDB用户使用。 我们开发了一个BSON库,它通过利用规范细节和我们能想到的每一个技巧,都胜过其他所有库。 序列化 在我们的BSON库中,序列化几乎不影响性能。 俩? 对于每种可能的操作,我们创建了一种专门执行该操作的专门算法。 两个操作可能共享相同的基本元数据要求,例如元素的位置。 为此,我们保留了文档中所有元素元数据的缓存。 这样,当一个操作第一次遇到一个元素时,其他操作就不需要花费时间了。 这样,我们可以高效地进行解析,并始终保持所有数据序列化。 这也意味着我们绝不会反序列化甚至读取不需要的数据。 这样可以节省CPU性能,内存副本和内存使用率,这是该库独有的。 利用规范 BSON的规范(http://bsonspec.org)具有始终位于消息核心的元素。 文献。 文档从Int32的整个长度开始,以空终止符结束。 规范中存储了长度和空终止符的原因是为了提高解析性能。 BSON可以递归嵌套文档。 因此,如果您想跳到同一级别的下一个元素,则这两个属性可以提高解析性能。 但是,如果要将元素添加到文档,则需要删除null终止符,添加该元素,然后再次添加null终止符。 并且在文档的内容更改之后,将执行其他操作以更新文档的长度。 这是没有问题的,直到您意识到此时添加5个属性会花费15个额外的堆操作。 而且堆非常昂贵。 因此,我们从顶级文档的内部存储中删除了Int32和null终止符。 这使这些操作的成本降低了四倍。 解析/提取 BSON的数据始终是序列化的,因此提取需要即时进行。 我们通过懒惰地搜索和反序列化文档中的信息来做到这一点。 在您要求我们提供某些信息之前,我们不知道文件的内容。 届时,我们将有效地解析文档,直到找到所需的信息。 这样,我们解析的内容不会超出我们的需要。 { “ username”:“ Joannis”, “年龄”:21岁, “男”:是的, “ admin”:是的, “权限”:[“全部”,“更多”,“无限”] } 如果您要访问键“用户名”,则将仅查看和缓存此“用户名”键,因为它是文档中的第一个实体。 不会扫描,缓存或查看“年龄”,“男性”,“管理员”和“权限”。 现在,当您访问male ,解析器将在username之后恢复并找到age而不反序列化值。 接下来,找到male ,将其击中,反序列化该值,停止扫描并返回该值。 现在,如果您请求age ,它已经知道age在哪里并反序列化此信息。 如果您寻找nonexistingkey ,它将一直扫描直到permissions不匹配为止,并将顶级文档标记为“完全扫描”,因此无需再次扫描。 防止将来无用的扫描无法阅读文档末尾。 如果由于某种原因您需要访问权限的第二个[1]属性,它根本不会提取permissions文档。 而是以递归的方式开始扫描permissions内的值,就像使用顶级文档一样。 […]