用 PHP 处理 10 亿行数据!

已有500人围观 来源:21CTO 发布于:2024-04-10 12:48:04

今天,我将带大家一起走进“挑衅十亿行“数据的世界。

当然,这个事情是依据GitHub上的一个“十亿行挑衅”(1brc)运动而来,现在正在进行,如果你没有听说过,可查看Gunnar Morlings 的 1brc 存储库。

https://github.com/gunnarmorling/1brc

我之所以被吸引,是因为社区中的两位同事加入了竞赛。以下地址是全球各地开发者的代码排行榜。

https://github.com/gunnarmorling/1brc?tab=readme-ov-file#results

图1 10亿行代码处置速度排行榜

我只截图一小部分,感兴致的朋友还可以阅读上面的网址。

应用PHP加入速度排行榜

大家知道,PHP 并不以速度最快而著名。在我开发 PHP 剖析器时,我想应当尝试一下它,看看能到达多快的速度。

第一种,最“幼稚”的办法


我克隆了存储库,下载了measurements.txt(一个csv格局文件)后,我开端构建第一个最“天真纯朴”的实现,但是能够解决这个挑衅。


代码如下:

<?php
$stations = [];
$fp = fopen('measurements.txt', 'r');
while ($data = fgetcsv($fp, null, ';')) { if (!isset($stations[$data[0]])) { $stations[$data[0]] = [ $data[1], $data[1], $data[1], 1 ]; } else { $stations[$data[0]][3] ++; $stations[$data[0]][2] += $data[1]; if ($data[1] < $stations[$data[0]][0]) { $stations[$data[0]][0] = $data[1]; } if ($data[1] > $stations[$data[0]][1]) { $stations[$data[0]][1] = $data[1]; } }}
ksort($stations);
echo '{';foreach($stations as $k=>&$station) { $station[2] = $station[2]/$station[3]; echo $k, '=', $station[0], '/', $station[2], '/', $station[1], ', ';}echo '}';


这里没什么可夸耀的,我们先打开文件,然后用来fgetcsv()函数来读取数据。如果未找到元素,则创立新的空的stations数组和相应列,如要有数据则增长计数,对温度求和,并查看当前温度是否低于或高于最小值或最大值,并做相应的更新。

我把所有东西都放在一起,应用ksort()按$stations数组次序排列,然后回显数组并盘算平均温度(总和/计数)。

简略描写完算法,然后在我的笔记本电脑上运行了这个简略代码,它须要25 分钟。