加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

java – 提高协议缓冲区的性能

发布时间:2020-12-15 00:10:04 所属栏目:Java 来源:网络整理
导读:我正在编写一个应用程序,需要从单个文件中快速反序列化数百万条消息. 应用程序的作用主要是从文件中获取一条消息,做一些工作然后丢弃消息.每条消息由~100个字段组成(并非所有消息都被解析,但我需要它们,因为应用程序的用户可以决定他想要处理哪些字段). 在这
我正在编写一个应用程序,需要从单个文件中快速反序列化数百万条消息.

应用程序的作用主要是从文件中获取一条消息,做一些工作然后丢弃消息.每条消息由~100个字段组成(并非所有消息都被解析,但我需要它们,因为应用程序的用户可以决定他想要处理哪些字段).

在这一刻,应用程序包含一个循环,在每次迭代中使用readDelimitedFrom()调用执行.

有没有办法优化问题,以更好地适应这种情况(拆分多个文件等…).另外,在这一刻由于消息的数量和每条消息的维度,我需要gzip文件(并且它在减小大小方面相当有效,因为字段的值非常重复) – 这虽然减少了性能.

解决方法

如果CPU时间是你的瓶颈(如果你直接从具有冷缓存的硬盘加载,这是不太可能的,但在其他情况下可能就是这种情况),那么这里有一些方法可以提高吞吐量:

>如果可能,使用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.这些算法仍然获得合理的压缩比,但针对速度进行了优化. (LZ4可能更好,虽然Snappy是由Google开发的Protobufs开发的,所以你可能想在你的数据集上测试它们.)
>考虑使用Cap’n Proto而不是Protocol Buffers.不幸的是,还没有Java版本,但编辑:有capnproto-java,还有许多其他语言的实现.在它支持的语言中已经证明它要快得多. (披露:我是Cap’n Proto的作者.我也是Protocol Buffers v2的作者,这是谷歌发布的开源版本.)

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读