
Парсинг JSON в Python досягає 66 ГБ/с з fastsimdjson та free threading
Журнал подій GitHub об'ємом 7,6 ГБ був оброблений за 0,12 секунди з Python 3.14.6, fastsimdjson 0.6.0, lazy views та 64 потоками. Бенчмарк порахував 65 269 pull request, серед яких лідирують TypeScript, JavaScript, Python та Java.
Що виміряли
Денієл Лемір використав вісім годин подій публічних репозиторіїв GitHub від 13 березня 2024 року, які GH Archive зібрав у форматі NDJSON. Розпакований зразок становив 7,6 ГБ і містив 2,2 мільйона подій, в середньому приблизно 3,4 кБ кожна. Завдання полягало в підрахунку типів подій та для подій типу pull request, у яких action було opened, підрахунку мови базового репозиторію. За вісім годин Лемір порахував 65 269 відкритих pull request. Найбільші групи склали TypeScript з 11 565, JavaScript з 7 778, Python з 7 057 та Java з 4 668. Приблизно 5 857 відкритих pull request належали репозиторіям без вказаної мови.
Як парсер зберіг легкість
У роботі використовувався fastsimdjson, прив'язка simdjson для Python, разом з Python 3.14.6, на сервері з двома процесорами Intel Xeon Gold 6548N та 64 ядрами. У free threaded Python GIL не існує, і кілька потоків можуть одночасно виконувати код Python. Виклик map_many у fastsimdjson розподіляє рядки за вказаною кількістю потоків, а вхідні дані розділяє на частини. Кожен потік зберігає власну пару Counter, додає її до загального списку лише на першій події, а потім оновлює цю пару без синхронізації з іншими потоками. Головний потік об'єднує пари кожного потоку після повернення map_many. У випадку lazy = True кожен callback отримує lazy view замість словника. JSON все одно парситься, але об'єкти Python створюються лише для тих полів, до яких звертається код. Лемір зазначає, що lazy підхід вперше розробив Тайлер Кеннеді у прив'язці pysimdjson.
Результати бенчмарку
Дані перед вимірюванням часу розпаковували в пам'ять. Лемір повідомляє про найкращий результат із семи запусків, одним запуском для однопотокових парсерів та стандартної бібліотеки на 64 потоках. На одному ядрі стандартний парсер json бібліотеки працював зі швидкістю 0,18 ГБ/с, orjson 0,42 ГБ/с, fastsimdjson map_many 0,63 ГБ/с, типізовані структури msgspec 1,29 ГБ/с, а fastsimdjson map_many з lazy views 2,13 ГБ/с. Стандартній бібліотеці знадобилося 42 секунди на зразок, тоді як fastsimdjson з lazy views — 3,6 секунди. В одному процесі з використанням 64 потоків стандартна бібліотека досягла 3,17 ГБ/с, типізовані структури msgspec 24,6 ГБ/с, fastsimdjson map_many 29,8 ГБ/с, а lazy варіант 65,7 ГБ/с. Це приблизно 0,12 секунди для зразка 7,6 ГБ, приблизно 66 ГБ/с, тобто у 31 разів більше за однопотоковий результат. Результат lazy fastsimdjson також був швидшим, ніж msgspec з 64 потоками. За висновком Леміра, Python може парсити JSON зі швидкістю десятків гігабайт за секунду, а fastsimdjson 0.6.0 доступний у PyPI.
Джерела: Lobsters
SiTech — веброзробка з підтримкою AI
Створюємо швидкі та сучасні сайти й інтегруємо AI у бізнес-процеси. Маєте проєкт чи запитання? Із задоволенням допоможемо.