Как я обработал один миллиард строк в PHP

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.

Вероятно, вы уже слышали о соревновании под названием "The One Billion Row Challenge" (1brc), если же нет, то предлагаю ознакомиться с репозиторием 1brc Гуннара Морлинга.

Моё участие в проекте было мотивировано присутствием в нём двух моих коллег, которые достигли лидирующих позиций.

PHP не известен своими выдающимися скоростными показателями. Тем не менее, учитывая, что я работаю над профайлером PHP, я решил исследовать его производительность на примере этого вызова.

Первый наивный подход 

Я скопировал содержимое репозитория и сформировал датасет с миллиардом записей в текстовом файле measurements.txt. После этого приступил к разработке первоначальной, простейшей версии алгоритма, который мог бы выполнять поставленную передо мной задачу:

<?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(). Если станция ещё не была обнаружена, мы регистрируем её, если же она уже есть в нашем списке, то увеличиваем счётчик, добавляем значения температуры и обновляем минимальные и максимальные показатели при необходимости.

По завершении, я применяю функцию ksort() для сортировки массива $stations, после чего вывожу список станций, а также вычисляю среднюю температуру, разделив общую сумму на количество записей.

Эксперимент с этим базовым кодом на моём ноутбуке показал, что его выполнение занимает 25 минут

Источник: https://habr.com/ru/companies/bothub/articles/799469/


Интересные статьи

Интересные статьи

Для деплоя приложений в Kubernetes существует огромное количество различных инструментов. Если посмотреть на соответствующий раздел в CNCF Landscape, то можно потеряться в разнообразии. Поэтому иногда...
Джон Хортон Конвей (John Horton Conway), член Королевского общества, родом из Принстона, известен многими вещами, но возможно, больше всего своим любопытством и любовью ко всевозможным играм, которую ...
Как мы представляем себе кроссплатформенность? Мы пишем программу на языке, который либо компилируется в исполняемый файл отдельно для каждой поддерживаемой платформы, либо использует...
— Что вы скажете, если я попрошу вас разработать сервис, который обрабатывает тысячи запросов в секунду с минимальной задержкой? — Хм… Я скажу, что у вас в компании возникла такая проб...
Элита программисты или нет, достойны они сверхвысоких зарплат и заслуживают ли особого отношения — вопрос спорный. Очевидно только то, что программист — профессия немасштабируемая, поэтому сравне...