龙空技术网

十亿行数据挑战——用Java快速聚合文本文件中的10亿行的有趣探索

山行AI 23

前言:

现在你们对“十亿数据查询算法java”可能比较关怀,兄弟们都需要知道一些“十亿数据查询算法java”的相关资讯。那么小编同时在网络上搜集了一些关于“十亿数据查询算法java””的相关内容,希望小伙伴们能喜欢,你们快快来了解一下吧!

1️⃣️ 一亿行挑战

状态 1月1日:此挑战已开放提交!

一亿行挑战(1BRC)是一项有趣的探索,旨在了解现代Java在从文本文件中聚合十亿行数据方面的极限。拿起你的(虚拟)线程,使用SIMD,优化你的GC,或者尝试其他任何技巧,创建解决此任务的最快实现!

文本文件包含了一系列气象站的温度值。每行是一次测量,格式为<string: station name>;<double: measurement>,测量值精确到一位小数。以下是十行数据的示例:

汉堡;12.0布拉瓦约;8.9巨港;38.8圣约翰;15.2克拉科夫;12.6布里奇顿;26.9伊斯坦布尔;6.2罗索;34.4科纳克里;31.2伊斯坦布尔;23.0

任务是编写一个Java程序,读取文件,计算每个气象站的最低、平均和最高温度值,并按气象站名称字母顺序排序后,以<min>/<mean>/<max>的格式(结果值四舍五入到一位小数)输出到标准输出,如下所示:

{阿布哈=-23.0/18.0/59.2, 阿比让=-16.2/26.0/67.3, 阿贝歇=-10.0/29.4/69.0, 阿克拉=-10.1/26.4/66.4, 亚的斯亚贝巴=-23.7/16.0/67.0, 阿德莱德=-27.8/17.3/58.5, ...}

在2024年1月31日前提交你的实现,并成为排行榜的一员!

[1]结果

#

结果 (分:秒.毫秒)

实现方式

JDK

提交者

1.

00:11.495

链接[2]

21.0.1-graalce

Elliot Barlas[3]

2.

00:11.886

链接[4]

21.0.1-open

Dimitar Dimitrov[5]

3.

00:14.848

链接[6]

21.0.1-graalce

Sam Pullara[7]

4.

00:18.865

链接[8]

21.0.1-open

Nick Palmer[9]

5.

00:21.853

链接[10]

21.0.1-graal

Filip Hrisafov[11]

6.

00:23.366

链接[12]

21.0.1-open

Roy van Rijn[13]

7.

00:38.106

链接[14]

21.0.1-open

Markus Ebner[15]

8.

00:38.510

链接[16]

21.0.1-open

Hampus Ram[17]

9.

00:38.819

链接[18]

21.0.1-open

Richard Startin[19]

10.

00:50.547

链接[20]

21.0.1-open

Aurelian Tutuianu[21]

11.

00:53.679

链接[22]

21.0.1-open

Chris Riccomini[23]

12.

00:57.141

链接[24]

21.0.1-open

Roman Schweitzer[25]

13.

02:00.101

链接[26]

21.0.1-open

khmarbaise[27]

14.

02:08.315

链接[28]

21.0.1-open

itaske[29]

15.

02:08.650

链接[30]

21.0.1-open

Kuduwa Keshavram[31]

16.

04:13.449

链接[32] (基准)

21.0.1-open

Gunnar Morling[33]

查看下方[34]以了解如何使用你自己的实现参加挑战。

[35]先决条件

你的系统必须安装了Java 21[36]

[37]运行挑战

该仓库包含两个程序:

dev.morling.onebrc.CreateMeasurements(通过create_measurements.sh调用):在该项目的根目录下创建一个包含可配置数量的随机测量值的measurements.txt文件

dev.morling.onebrc.CalculateAverage(通过calculate_average.sh调用):计算文件measurements.txt的平均值

执行以下步骤来运行挑战:

1. 使用Apache Maven构建项目:

./mvnw clean verify

2. 创建包含10亿行的测量文件(只需一次):

./create_measurements.sh 1000000000

这将花费几分钟时间。注意:生成的文件大约为12 GB,所以确保有足够的磁盘空间。

3. 计算平均测量值:

./calculate_average.sh

提供的简单示例实现使用Java流API处理文件,并在用于结果评估[38]的环境中完成任务约需2分钟。它作为比较你自己实现的基准。

4. 尽情优化:

调整CalculateAverage程序以加快速度,你可以随意适合的方式(只需遵守下面描述的几条规则)。选项包括并行化计算、使用(孵化中的)Vector API、同时内存映射文件的不同部分、使用AppCDS、GraalVM、CRaC等加速应用程序启动、选择和调优垃圾收集器,以及更多。

[39]火焰图/性能分析

一个提示是,如果你安装了jbang[40],你可以通过运行以下命令获取程序的火焰图:

jbang --javaagent=ap-loader@jvm-profiling-tools/ap-loader=start,event=cpu,file=profile.html -m dev.morling.onebrc.CalculateAverage_yourname target/average-1.0.0-SNAPSHOT.jar

或者直接在.java文件上:

jbang --javaagent=ap-loader@jvm-profiling-tools/ap-loader=start,event=cpu,file=profile.html src/main/java/dev/morling/onebrc/CalculateAverage_yourname

当你运行这个命令时,它将在profile.html中生成一个火焰图。然后你可以在浏览器中打开它,查看你的程序在哪里花费时间。

[41]规则和限制

•可以使用以下任何Java发行版:

•由SDKMan[42]提供的任何构建

•openjdk.net上提供的早期访问构建可以使用(包括OpenJDK项目如Valhalla的EA构建)

builds.shipilev.net[43]上的构建如果你想使用这些渠道之外的构建,请联系讨论是否可以考虑。•不得使用外部库依赖

•实现必须提供为单个源文件

•计算必须在应用程序运行时发生,即你不能在构建时处理测量文件(例如,使用GraalVM)并只将结果烘焙到二进制文件中

[44]参加挑战

要将你自己的实现提交给1BRC,请按照以下步骤操作:

•创建一个onebrc[45] GitHub仓库的分支。

•创建一个CalculateAverage.java的副本,命名为CalculateAverage_.java,例如CalculateAverage_doloreswilson.java。

•使该实现快速。非常快速。

•创建一个calculate_average.sh的副本,命名为calculate_average_.sh,例如calculate_average_doloreswilson.sh。

•调整该脚本,使其引用你的实现类名。如有需要,通过脚本中的JAVA_OPTS变量提供任何JVM参数。

•OpenJDK 21是默认的。如果需要定制的JDK构建,请在应用启动前的启动脚本中包含SDKMAN命令sdk use java [version]

•(可选)如果你想使用原生二进制文件(GraalVM),调整pom.xml文件以构建该二进制文件。•创建一个针对上游仓库的拉取请求,明确说明

•你的实现类的名称。

•程序在你的系统上的执行时间以及同样的规格(CPU,核心数,RAM)。这仅为参考,官方运行时间将如下面描述的那样确定。

•我将运行程序并确定其性能,如下一节所述,并将结果输入计分板。

注意:如果我对实现感到怀疑,我保留不评估特定提交的权利(即我不会运行你的比特币矿工;)。

如果你想与社区讨论任何有关实现1BRC的潜在想法,你可以使用该仓库的GitHub讨论[46]。请保持友好和文明。

挑战进行到2024年1月31日。2024年1月31日23:59 UTC之后创建的任何提交(即拉取请求)将不予考虑。

[47]评估结果

结果由在Hetzner Cloud CCX33实例[48]上运行程序确定(8个专用vCPU,32 GB RAM)。使用time程序来测量执行时间,即测量端到端时间。每个竞争者将连续运行五次。最慢和最快的运行将被丢弃。其余三次运行的平均值是该竞争者的结果,并将添加到上面的结果表中。用于评估所有竞争者的是完全相同的measurements.txt文件。

如果你想在Hetzner Cloud上为测试自己搭建一个盒子,你可能会发现这些设置脚本[49](基于Terraform和Ansible)有用。请注意,这将产生你需要负责的费用,我不会支付你的云账单:)

[50]奖品

如果你参加这个挑战,你可能会学到新东西,激励他人,并为在上面的计分板上看到你的名字感到自豪。据传闻,获胜者还可能收到一件独一无二的1️⃣️ T恤!

[51]常见问题解答

问:我可以使用Kotlin或Java以外的其他JVM语言吗?

答:不可以,这个挑战仅限于Java。不过,欢迎非正式分享显著优于任何列出结果的实现。

问:我可以使用非JVM语言和/或工具吗?

答:不可以,这个挑战仅限于Java。不过,欢迎非正式分享有趣的实现和结果。例如,看看DuckDB在这个任务中的表现将会很有趣。

问:我有一个实现——但它不是用Java写的。我可以在哪里分享它?

答:虽然非Java解决方案不能正式提交给挑战,但欢迎你在GitHub讨论区的展示和讲述[52]中分享它们。

问:我可以使用JNI吗?

答:提交作品必须完全用Java实现,即不能编写C/C++的JNI粘合代码。不过,你可以通过GraalVM对Java代码进行AOT编译,无论是AOT编译整个应用程序,还是创建本地库(见这里[53])。

问:measurements.txt文件的编码是什么?

答:该文件使用UTF-8编码。

问:我可以对数据集中出现的气象站名称做出假设吗?

答:不可以,虽然数据集生成器仅使用固定集合的站点名称,但任何解决方案都应该适用于任意UTF-8站点名称(为简单起见,保证名称不含有;字符)。

问:我可以复制其他提交的代码吗?

答:可以,这个挑战的主要焦点是学习新东西,而不是"赢得比赛"。当你这样做时,请向相关的提交来源表示致谢。请不要重新提交没有或只有微小改进的其他参赛作品。

问:为什么是1️⃣️

答:这是项目名称的缩写:One Billion Row Challenge。

[54]许可

此代码库可在Apache License版本2下使用。

[55]行为准则

彼此尊重!这个挑战的目的不仅仅是赢得比赛,更重要的是要有乐趣并学习新东西。

引用

更多信息请参考:

References

[1] :

[2] 链接:

[3] Elliot Barlas:

[4] 链接:

[5] Dimitar Dimitrov:

[6] 链接:

[7] Sam Pullara:

[8] 链接:

[9] Nick Palmer:

[10] 链接:

[11] Filip Hrisafov:

[12] 链接:

[13] Roy van Rijn:

[14] 链接:

[15] Markus Ebner:

[16] 链接:

[17] Hampus Ram:

[18] 链接:

[19] Richard Startin:

[20] 链接:

[21] Aurelian Tutuianu:

[22] 链接:

[23] Chris Riccomini:

[24] 链接:

[25] Roman Schweitzer:

[26] 链接:

[27] khmarbaise:

[28] 链接:

[29] itaske:

[30] 链接:

[31] Kuduwa Keshavram:

[32] 链接:

[33] Gunnar Morling:

[34] 下方:

[35] :

[36] Java 21:

[37] :

[38] 结果评估:

[39] :

[40] jbang:

[41] :

[42] SDKMan:

[43] builds.shipilev.net:

[44] :

[45] onebrc:

[46] GitHub讨论:

[47] :

[48] Hetzner Cloud CCX33实例:

[49] 设置脚本:

[50] :

[51] :

[52] 展示和讲述:

[53] 这里:

[54] :

[55] :

标签: #十亿数据查询算法java