微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

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

应用程序的作用主要是从文件获取一条消息,做一些工作然后丢弃消息.每条消息由~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的作者,这是谷歌发布的开源版本.)

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐