Я замінив JSON на власний бінарний формат у PHP

Нам потрібно зберігати багатоформатний текст для веб- та мобільних застосунків.

Роками ми використовували чистий HTML у нашій базі даних. Згодом ми перейшли на JSON, щоб відокремити процес редагування від друку.

JSON став проблемою в міру зростання обсягів наших даних. Щоб змінити лише одне посилання, нам доводилося парсити, перебудовувати та перетворювати на рядок увесь масив. Цей процес був повільним і неефективним.

Я вирішив розробити власний бінарний формат за допомогою PHP.

Ось чому я зробив цей перехід:

  • Швидкість: парсинг і пошук стали набагато швидшими.
  • Контроль: я можу маніпулювати окремими байтами, не завантажуючи все в пам'ять.
  • Структура: я перейшов від вкладеного дерева до плоского списку елементів.

Більшості завдань із багатоформатним текстом не потрібне складне дерево. Часто потрібно лише знайти текст або певні теги. Плоска структура елементів із простим деревом зміщень працює краще.

PHP не є мовою низького рівня. Він не оптимізований для маніпуляцій з байтами, як Zig або C. Проте PHP має відповідні інструменти:

  • pack() перетворює числа або рядки на сирі байти.
  • unpack() перетворює ці байти назад у придатні для використання дані.

Я припинив використовувати функції для багатобайтових рядків. Замість цього я зчитую конкретні фрагменти байтів. Наприклад, беззнакове 64-бітне ціле число потребує рівно 8 байтів.

Результати після 10 000 циклів:

Старе кодування JSON: 2.18s Старе декодування JSON: 0.86s Нове бінарне кодування: 1.19s Нове бінарне декодування: 0.67s

Бінарний формат швидший. Але він також більший. Його розмір у 2 рази перевищує розмір JSON і в 3 рази — розмір HTML. Оскільки ми використовуємо рендеринг на стороні сервера, для нас це не має значення.

Якщо ви створюєте власний формат, дотримуйтесь одного правила: напишіть специфікацію. Чітко задокументуйте свій формат. Ви пошкодуєте, якщо цього не зробите.

Це зайняло тиждень роботи. Воно того варте.

Джерело: https://dev.to/tomj/i-replaced-json-with-a-custom-binary-format-in-php-mok