改善协议缓冲区的性能

塞巴斯蒂安诺·梅利诺(Sebastiano Merlino)

我正在编写一个需要从单个文件快速反序列化数百万条消息的应用程序。

应用程序要做的实际上是从文件中获取一条消息,做一些工作,然后丢弃该消息。每条消息都由约100个字段组成(并非总是解析所有字段,但我需要全部这些字段,因为应用程序的用户可以决定他要处理的字段)。

此时,应用程序包含一个循环,该循环在每次迭代中仅使用readDelimitedFrom()调用执行

有没有一种方法可以优化问题以更好地适应这种情况(拆分为多个文件等)。此外,由于邮件数量和每封邮件的尺寸,此刻,我需要对文件进行gzip压缩(由于字段的值非常重复,因此可以有效地减小文件大小)-尽管这会减少性能。

肯顿·瓦尔达(Kenton Varda)

如果CPU时间是您的瓶颈(如果直接从具有冷缓存的HDD加载是不太可能的,但是在其他情况下可能是这种情况),那么可以通过以下几种方法来提高吞吐量:

  • 如果可能,请使用C ++而不是Java,并在循环的每次迭代中重用相同的消息对象。这减少了在内存管理上花费的时间,因为每次都会重复使用相同的内存。

  • 而不是使用readDelimitedFrom()而是构造一个CodedInputStream并使用它来读取多个消息,如下所示:

    // Do this once:
    CodedInputStream cis = CodedInputStream.newInstance(input);
    
    // Then read each message like so:
    int limit = cis.pushLimit(cis.readRawVarint32());
    builder.mergeFrom(cis);
    cis.popLimit(limit);
    cis.resetSizeCounter();
    

    (一种类似的方法在C ++中起作用。)

  • 使用Snappy或LZ4压缩而不是gzip。这些算法仍可获得合理的压缩率,但针对速度进行了优化。(尽管Snappy是Google考虑到Protobufs开发的,但LZ4可能更好一些,因此您可能要在数据集上对它们进行测试。)

  • 考虑使用Cap'n Proto而非协议缓冲区。不幸的是,还没有Java版本,但是编辑:有capnproto-java以及许多其他语言的实现。在它支持的语言中,已经证明它要快得多。(公开:我是Cap'n Proto的作者。我还是Protocol Buffers v2(这是Google发布的开源版本)的作者。)

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

带反射的嵌套协议缓冲区

来自分类Dev

Java协议缓冲区-反射

来自分类Dev

在C ++中解析协议缓冲区

来自分类Dev

Scala Akka和协议缓冲区

来自分类Dev

带有协议缓冲区的RPC

来自分类Dev

协议缓冲区Wireshark插件

来自分类Dev

协议缓冲区消息的字节序

来自分类Dev

协议缓冲区:版本更改

来自分类Dev

REST是否支持协议缓冲区

来自分类Dev

损坏的协议缓冲区消息

来自分类Dev

协议缓冲区-分配嵌套消息

来自分类Dev

Ionic 4协议缓冲区

来自分类Dev

协议缓冲区损坏数据

来自分类Dev

在协议缓冲区中分隔消息

来自分类Dev

Java协议缓冲区-消息大小

来自分类Dev

带反射的嵌套协议缓冲区

来自分类Dev

谷歌协议缓冲区漂亮的打印

来自分类Dev

带有CMakeLists的协议缓冲区

来自分类Dev

协议缓冲区与 codelite 的静态链接

来自分类Dev

多个缓冲区和VAO性能

来自分类Dev

在协议缓冲区消息中存储二进制数据缓冲区

来自分类Dev

协议缓冲区-重复布尔值的最佳实践

来自分类Dev

无法获取Google协议缓冲区进行编译

来自分类Dev

纯虚拟方法称为错误Google协议缓冲区

来自分类Dev

Golang Google协议缓冲区中的错误

来自分类Dev

使用协议缓冲区的Python项目,部署问题

来自分类Dev

协议缓冲区-唯一编号标签-澄清吗?

来自分类Dev

协议缓冲区和枚举组合?

来自分类Dev

如何在Swift中附加协议缓冲区?