问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

这波操作看麻了!十亿行数据,从71s到1.7s的优化之路。

创作时间:
作者:
@小白创作中心

这波操作看麻了!十亿行数据,从71s到1.7s的优化之路。

引用
1
来源
1.
https://www.cnblogs.com/thisiswhy/p/18051585

在2024年1月份,一场名为《The One Billion Row Challenge》(简称1BRC)的编程挑战赛吸引了众多Java开发者的关注。这场挑战要求参赛者解析一个包含10亿行气象数据的文件,并计算出每个气象站的最小、最大和平均温度。本文将详细解析这场挑战的赛题要求、优化过程以及最终的优化成果。

赛题介绍

在2024年1月1日,Gunnar Morling发布了一篇关于1BRC挑战的文章。赛题要求解析一个包含10亿行气象数据的文件,每行记录了一个气象站的温度值,格式为"气象站;温度",温度值保留一位小数。参赛者需要计算出每个气象站的最小、最大和平均温度,并按照字典序输出结果。

为了帮助理解,这里给出一个简短的例子:

chengdu;12.0
guangzhou;7.2
chengdu;6.3
beijing;-3.6
chengdu;23.0
shanghai;9.8
chengdu;24.3
beijing;17.8

对于成都(chengdu),最低气温是6.3,最高气温是24.3,平均气温是(12.0+6.3+23.0+24.3)/4=16.4。

出题人还提供了一个基线版本的代码实现,使用了流式编程,但在作者的电脑上运行时间接近14分钟。

优化过程

巨人肩膀:Marko Topolnik的优化之路

在官方GitHub项目中,Marko Topolnik分享了他的优化过程,从最初的71秒优化到了1.7秒。以下是他的优化步骤:

最常规的代码

首先,他给出了一个常规实现的代码,使用并行流处理数据。在Hetzner CCX33机器上,运行时间为71秒。

第0版优化:更换JVM

作者尝试使用GraalVM替代默认的JVM,运行时间从71秒减少到66秒。

数据指标的重要性

在正式优化之前,作者使用了三个重要的工具来收集程序的运行指标,包括火焰图和GC情况。

第一版优化:并行I/O

通过分析火焰图,发现性能瓶颈主要在BufferedReader和字符串处理上。作者采用MemorySegment进行并行I/O读取,将运行时间从66秒减少到17秒。

第二版优化:优化温度解析

将温度解析为整数,避免了字符串到浮点数的转换,运行时间进一步减少到11秒。

第三版优化:自定义哈希表

由于只有413个气象站,作者设计了一个自定义的哈希表,使用开放寻址法解决冲突,将运行时间降低到6.6秒。

第四版优化:使用Unsafe和SWAR

这一版使用了Unsafe避免边界检查,使用SWAR技术处理数据,将运行时间降低到2.4秒。

第五版优化:统计学应用

通过统计分析发现,气象站名称长度的分布特点,进一步优化字符串比较逻辑,将运行时间降低到1.8秒。

进一步优化

作者还尝试了消除启动/清理成本和使用更小的文件分块等优化手段,最终将运行时间优化到1.7秒。

总结

这场挑战赛展示了Java编程中各种高级优化技术的应用,包括并行I/O、自定义数据结构、位操作优化等。虽然这些优化在实际业务开发中可能并不常见,但它们展示了Java编程的深度和可能性。对于Java开发者来说,了解这些优化技巧,不仅可以提升代码性能,更能拓宽技术视野。

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号