如何在不移动数据的情况下使用零拷贝序列化库?
How to use zero-copy serialization libraries without moving the data?
我正在寻找一个二进制序列化库,因为 JSON 对于我们的用例来说太慢了。一些 lib 开发者(Flatbuffers,Cap'n Proto,..)反对 Protobuf,因为它不遵循零拷贝的想法(例如 1 and 2)。
当我考虑如何将任何这些库集成到我们的代码中时,我发现 1 中的 "Usable as mutable state" 点有问题。
这基本上是说零拷贝特性导致(大部分)不可变对象。所以我需要一份我自己 class 中所有(或大部分)字段的副本,以便能够 modify/write 数据("mutable state")。
在这种情况下,我总是需要将我的内部状态复制到序列化程序对象——这不像零复制。
Protobuf 有何不同?* 我可以将该对象用作我的可变内部状态(或者这有什么问题吗?)并且从那里它也需要我只需一份即可获得序列化对象。
* 对于您不仅读取数据的任何用例..
如果您的用例涉及突变,那么与 Protobuf 相比,零拷贝库的优势确实缩小了。
FlatBuffers 有 3 种方式进行变异:
- 如果仅对标量进行突变,则可以就地对其进行突变 (
--gen-mutable
),这非常有限但也非常有效。
- 如果突变很少见,您仍然可以使用反射就地进行它们。这允许更多种类的突变,但使用起来缓慢且复杂。
- 您可以使用对象 API (
--gen-object-api
)。这会生成一个类似于 Protobuf 的 API,它完全可变且易于使用,但当然会分配更多的内存。与 Protobuf 相比,使用它仍然有优势,因为 API 更符合 C++ 的习惯,de/encoding 可能仍然更快,如果您的系统的某些部分不需要变异,它们可以使用更快的底层 API.
我正在寻找一个二进制序列化库,因为 JSON 对于我们的用例来说太慢了。一些 lib 开发者(Flatbuffers,Cap'n Proto,..)反对 Protobuf,因为它不遵循零拷贝的想法(例如 1 and 2)。 当我考虑如何将任何这些库集成到我们的代码中时,我发现 1 中的 "Usable as mutable state" 点有问题。 这基本上是说零拷贝特性导致(大部分)不可变对象。所以我需要一份我自己 class 中所有(或大部分)字段的副本,以便能够 modify/write 数据("mutable state")。 在这种情况下,我总是需要将我的内部状态复制到序列化程序对象——这不像零复制。
Protobuf 有何不同?* 我可以将该对象用作我的可变内部状态(或者这有什么问题吗?)并且从那里它也需要我只需一份即可获得序列化对象。
* 对于您不仅读取数据的任何用例..
如果您的用例涉及突变,那么与 Protobuf 相比,零拷贝库的优势确实缩小了。
FlatBuffers 有 3 种方式进行变异:
- 如果仅对标量进行突变,则可以就地对其进行突变 (
--gen-mutable
),这非常有限但也非常有效。 - 如果突变很少见,您仍然可以使用反射就地进行它们。这允许更多种类的突变,但使用起来缓慢且复杂。
- 您可以使用对象 API (
--gen-object-api
)。这会生成一个类似于 Protobuf 的 API,它完全可变且易于使用,但当然会分配更多的内存。与 Protobuf 相比,使用它仍然有优势,因为 API 更符合 C++ 的习惯,de/encoding 可能仍然更快,如果您的系统的某些部分不需要变异,它们可以使用更快的底层 API.