状态 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日前提交你的实现,并成为排行榜的一员!
# | 结果 (分:秒.毫秒) | 实现方式 | 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]以了解如何使用你自己的实现参加挑战。
你的系统必须安装了Java 21[36]。
该仓库包含两个程序:
•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等加速应用程序启动、选择和调优垃圾收集器,以及更多。
一个提示是,如果你安装了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中生成一个火焰图。然后你可以在浏览器中打开它,查看你的程序在哪里花费时间。
•可以使用以下任何Java发行版:•由SDKMan[42]提供的任何构建•openjdk.net上提供的早期访问构建可以使用(包括OpenJDK项目如Valhalla的EA构建)•builds.shipilev.net[43]上的构建如果你想使用这些渠道之外的构建,请联系讨论是否可以考虑。•不得使用外部库依赖•实现必须提供为单个源文件•计算必须在应用程序运行时发生,即你不能在构建时处理测量文件(例如,使用GraalVM)并只将结果烘焙到二进制文件中
要将你自己的实现提交给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之后创建的任何提交(即拉取请求)将不予考虑。
结果由在Hetzner Cloud CCX33实例[48]上运行程序确定(8个专用vCPU,32 GB RAM)。使用time
程序来测量执行时间,即测量端到端时间。每个竞争者将连续运行五次。最慢和最快的运行将被丢弃。其余三次运行的平均值是该竞争者的结果,并将添加到上面的结果表中。用于评估所有竞争者的是完全相同的measurements.txt文件。
如果你想在Hetzner Cloud上为测试自己搭建一个盒子,你可能会发现这些设置脚本[49](基于Terraform和Ansible)有用。请注意,这将产生你需要负责的费用,我不会支付你的云账单:)
如果你参加这个挑战,你可能会学到新东西,激励他人,并为在上面的计分板上看到你的名字感到自豪。据传闻,获胜者还可能收到一件独一无二的1️⃣🐝🏎️ T恤!
问:我可以使用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。
此代码库可在Apache License版本2下使用。
彼此尊重!这个挑战的目的不仅仅是赢得比赛,更重要的是要有乐趣并学习新东西。
更多信息请参考:https://github.com/gunnarmorling/1brc
[1]
: https://github.com/gunnarmorling/1brc#results
[2]
链接: https://github.com/gunnarmorling/1brc/blob/main/src/main/java/dev/morling/onebrc/CalculateAverage_ebarlas.java
[3]
Elliot Barlas: https://github.com/ebarlas
[4]
链接: https://github.com/gunnarmorling/1brc/blob/main/src/main/java/dev/morling/onebrc/CalculateAverage_ddimtirov.java
[5]
Dimitar Dimitrov: https://github.com/ddimtirov
[6]
链接: https://github.com/gunnarmorling/1brc/blob/main/src/main/java/dev/morling/onebrc/CalculateAverage_spullara.java
[7]
Sam Pullara: https://github.com/spullara
[8]
链接: https://github.com/gunnarmorling/1brc/blob/main/src/main/java/dev/morling/onebrc/CalculateAverage_palmr.java
[9]
Nick Palmer: https://github.com/palmr
[10]
链接: https://github.com/gunnarmorling/1brc/blob/main/src/main/java/dev/morling/onebrc/CalculateAverage_filiphr.java
[11]
Filip Hrisafov: https://github.com/filiphr
[12]
链接: https://github.com/gunnarmorling/1brc/pull/5/
[13]
Roy van Rijn: https://github.com/royvanrijn
[14]
链接: https://github.com/gunnarmorling/1brc/blob/main/src/main/java/dev/morling/onebrc/CalculateAverage_seijikun.java
[15]
Markus Ebner: https://github.com/seijikun
[16]
链接: https://github.com/gunnarmorling/1brc/blob/main/src/main/java/dev/morling/onebrc/CalculateAverage_bjhara.java
[17]
Hampus Ram: https://github.com/bjhara
[18]
链接: https://github.com/gunnarmorling/1brc/blob/main/src/main/java/dev/morling/onebrc/CalculateAverage_richardstartin.java
[19]
Richard Startin: https://github.com/richardstartin
[20]
链接: https://github.com/gunnarmorling/1brc/blob/main/src/main/java/dev/morling/onebrc/CalculateAverage_padreati.java
[21]
Aurelian Tutuianu: https://github.com/padreati
[22]
链接: https://github.com/gunnarmorling/1brc/blob/main/src/main/java/dev/morling/onebrc/CalculateAverage_criccomini.java
[23]
Chris Riccomini: https://github.com/criccomini
[24]
链接: https://github.com/gunnarmorling/1brc/blob/main/src/main/java/dev/morling/onebrc/CalculateAverage_truelive.java
[25]
Roman Schweitzer: https://github.com/truelive
[26]
链接: https://github.com/gunnarmorling/1brc/blob/main/src/main/java/dev/morling/onebrc/CalculateAverage_khmarbaise.java
[27]
khmarbaise: https://github.com/khmarbaise
[28]
链接: https://github.com/gunnarmorling/1brc/blob/main/src/main/java/dev/morling/onebrc/CalculateAverage_itaske.java
[29]
itaske: https://github.com/itaske
[30]
链接: https://github.com/gunnarmorling/1brc/blob/main/src/main/java/dev/morling/onebrc/CalculateAverage_kuduwa_keshavram.java
[31]
Kuduwa Keshavram: https://github.com/kuduwa_keshavram
[32]
链接: https://github.com/gunnarmorling/onebrc/blob/main/src/main/java/dev/morling/onebrc/CalculateAverage.java
[33]
Gunnar Morling: https://github.com/gunnarmorling
[34]
下方: https://github.com/gunnarmorling/1brc#entering-the-challenge
[35]
: https://github.com/gunnarmorling/1brc#prerequisites
[36]
Java 21: https://openjdk.org/projects/jdk/21/
[37]
: https://github.com/gunnarmorling/1brc#running-the-challenge
[38]
结果评估: https://github.com/gunnarmorling/1brc#evaluating-results
[39]
: https://github.com/gunnarmorling/1brc#flamegraphprofiling
[40]
jbang: https://jbang.dev/
[41]
: https://github.com/gunnarmorling/1brc#rules-and-limits
[42]
SDKMan: https://sdkman.io/jdks
[43]
builds.shipilev.net: https://builds.shipilev.net/openjdk-jdk-lilliput/
[44]
: https://github.com/gunnarmorling/1brc#entering-the-challenge
[45]
onebrc: https://github.com/gunnarmorling/onebrc/
[46]
GitHub讨论: https://github.com/gunnarmorling/onebrc/discussions
[47]
: https://github.com/gunnarmorling/1brc#evaluating-results
[48]
Hetzner Cloud CCX33实例: https://www.hetzner.com/cloud
[49]
设置脚本: https://github.com/gunnarmorling/cloud-boxes/
[50]
: https://github.com/gunnarmorling/1brc#prize
[51]
: https://github.com/gunnarmorling/1brc#faq
[52]
展示和讲述: https://github.com/gunnarmorling/1brc/discussions/categories/show-and-tell
[53]
这里: https://www.graalvm.org/22.0/reference-manual/native-image/ImplementingNativeMethodsInJavaWithSVM/
[54]
: https://github.com/gunnarmorling/1brc#license
[55]
: https://github.com/gunnarmorling/1brc#code-of-conduct