«Переходи на Spark», говорили они. Сравнил pandas, Polars, DuckDB и PySpark на слабой машине

Gregory_Bondarenko 1 минуту назад «Переходи на Spark», говорили они. Сравнил pandas, Polars, DuckDB и PySpark на слабой машине 10 мин 0 Python * Big Data * Data Engineering * SQL * Компьютерное железо Аналитика Из...
<5 — 2026'da uzaya kaç SpaceX Starship fırlatması ulaşacak?
Вот важная новость с фронта ИИ: Gregory_Bondarenko 1 минуту назад «Переходи на Spark», говорили они. Сравнил pandas, Polars, DuckDB и PySpark на слабой машине 10 мин 0 Python * Big Data * Data Engineering * SQL * Компьютерное железо Аналитика Из песочницы Сценарий знакомый: открываешь в pandas файл побольше, ноутбук задумывается, вентилятор набирает обороты, и через минуту всё падает с MemoryError. Следом обычно приходит совет от старших коллег или из интернета: pandas для маленьких данных, для больших есть Spark.
Мне захотелось проверить этот совет цифрами. Не на кластере в облаке, где Spark чувствует себя как дома, а на машине, которая больше похожа на рабочий ноутбук аналитика. Для этого я написал небольшую программу TableBench.
Технические детали
Она сама генерирует данные, прогоняет одни и те же задачи на разных библиотеках, меряет время и память и следит, чтобы все посчитали одно и то же. Код открыт, ссылка в конце, и повторить замеры у себя можно одной командой. Статья для тех, кто уверенно пишет на pandas и слышал про Polars и DuckDB, но руки до них пока не дошли.
Сравнений этих библиотек в интернете хватает, самое известное из них db-benchmark, который сейчас поддерживает команда DuckDB. Он гоняет задачи на мощном сервере и отвечает на вопрос, кто быстрее. Меня интересовало другое: что происходит, когда памяти мало, на каком объёме каждая библиотека сдаётся и какие ошибки легко допустить по дороге.
Кого и на чём сравнивалУчастников шесть. Обычный pandas и pandas с dtype_backend="pyarrow", когда данные внутри хранятся в формате Arrow. Polars в ленивом режиме, где запрос сначала описывается целиком и выполняется только на collect(), и тот же Polars с потоковым движком collect(engine="streaming который обрабатывает данные кусками.
Отраслевые последствия
DuckDB, встраиваемая аналитическая база, в которой пишешь обычный SQL прямо по parquet-файлам. И PySpark в локальном режиме на всех ядрах. Задач пять, и все они из повседневной работы:ОперацияЧто делаетЗагрузка в памятьчитает всю таблицу целикомФильтр и группировкафильтр по дате, группировка по двум полям, пять агрегатов (по мотивам запроса Q1 из TPC-H)Join двух таблицсоединяет позиции заказов с отфильтрованными заказами и считает выручку по приоритетамОконная функцияоставляет в каждом заказе самую дорогую позицию, аналог row_number() = 1Сортировка и записьсортирует всю таблицу по двум полям и пишет результат в parquetКод для каждой библиотеки я старался писать так, как на ней пишут в жизни.
Никакого экзотического тюнинга, но и никаких заведомо медленных приёмов. Из настроек задал только потолок памяти для Spark и DuckDB (60% доступной памяти) и число shuffle-партиций для Spark по числу ядер. Версии такие: pandas 3.
0 на Java 21, Python 3. Данные и машинаДанные устроены по мотивам схемы TPC-H, известного бенчмарка для баз данных. Есть таблица заказов orders и таблица позиций заказов lineitem, основная нагрузка приходится на вторую.
Этот прогресс даёт важные сигналы о будущем отрасли, и технологический мир внимательно наблюдает.






