如何在不移动数据的情况下使用零拷贝序列化库?

时间:2018-01-04 09:22:27

标签: serialization protocol-buffers flatbuffers

我正在寻找一个二进制序列化库,因为JSON对我们的用例来说太慢了。一些lib开发者(Flatbuffers,Cap'n Proto,...)反对Protobuf,因为它不遵循零拷贝的想法(例如12)。 当我考虑如何将任何这些库集成到我们的代码中时,我发现1中的“可用作为可变状态”的问题。 这基本上说零拷贝特征导致(大多数)不可变对象。所以我需要我自己类中所有(或大部分)字段的副本才能修改/写入数据(“可变状态”)。 在这种情况下,我总是需要将我的内部状态复制到序列化程序对象 - 这不像零拷贝。

Protobuf有什么不同?* 我可以使用该对象作为我可变的内部状态(或者有什么问题吗?)从那里它也只需要一个副本来获取序列化对象。

*适用于您不仅阅读数据的任何用例..

1 个答案:

答案 0 :(得分:1)

如果您的用例涉及变异,那么与Protobuf相比,零拷贝库的优势确实会缩小。

FlatBuffers有3种方法可以进行突变:

  • 如果突变只是标量,那么这些可以就地突变(apiVersion: v1 kind: Pod metadata: name: www spec: containers: - name: nginx image: nginx volumeMounts: - mountPath: /srv/www name: www-data readOnly: true - name: git-monitor image: kubernetes/git-monitor env: - name: GIT_REPO value: http://github.com/some/repo.git volumeMounts: - mountPath: /data name: www-data volumes: - name: www-data emptyDir: {} ),这是非常有限但也非常有效。
  • 如果突变非常罕见,您仍然可以使用反射就地进行。这允许更多种类的突变,但使用缓慢且复杂。
  • 您可以使用对象API(--gen-mutable)。这会生成与Protobuf类似的API,它完全可变且易于使用,但当然会进行更多的内存分配。使用它比使用Protobuf还有优势,因为API是更惯用的C ++,de /编码可能仍然更快,如果你的系统的某些部分不需要变异,他们可以使用更快的底层API。