Zastąpiłem JSON własnym formatem binarnym w PHP

Potrzebowaliśmy lepszego sposobu na przechowywanie bogatego tekstu (rich text) dla naszych aplikacji i stron internetowych.

Na początku przechowywaliśmy surowy HTML w naszej bazie danych. Później przeszliśmy na JSON, aby oddzielić edycję od wyświetlania. JSON sprawdzał się przez jakiś czas, ale wraz z naszym rozwojem zaczął generować nowe problemy.

JSON stał się zbyt wolny dla naszych potrzeb.

Gdy musieliśmy przeszukiwać i aktualizować stare linki, musieliśmy parsuć i przebudowywać całe tablice. Proces ten był powolny i nieefektywny. Potrzebowaliśmy formatu, który umożliwiłby szybszą manipulację danymi i ich strumieniowanie.

Postanowiłem zbudować własny format binarny przy użyciu PHP.

Wielu programistów uważa, że PHP nie jest przystosowane do niskopoziomowego zarządzania bajtami. Jednak PHP posiada do tego wbudowane funkcje:

  • pack(): Konwertuje liczby lub ciągi znaków na surowe bajty.
  • unpack(): Konwertuje te bajty z powrotem na liczby lub ciągi znaków.

Przestałem używać operacji na wielobajtowych ciągach znaków (multibyte string operations). Zamiast tego skupiłem się na odczytywaniu konkretnych fragmentów bajtów. Na przykład, bez znaku 64-bitowa liczba całkowita wymaga dokładnie 8 bajtów. Precyzja jest kluczowa przy pracy z danymi binarnymi.

Zmieniłem również sposób strukturyzowania danych.

Większość osób próbuje przechowywać dokumenty w głębokiej, zagnieżdżonej strukturze drzewiastej. To często błąd. Przeszedłem na płaską listę elementów, takich jak tekst, tagi i listy. Do odbudowy HTML używam prostego drzewa przesunięć (offsets). Dzięki temu zadania takie jak znajdowanie wszystkich linków czy usuwanie tagów HTML są bardzo szybkie.

Wyniki z 10 000 pętli wskazują wyraźnego zwycięzcę:

Stare kodowanie JSON: 2,18 s Stare dekodowanie JSON: 0,86 s

Nowe kodowanie binarne: 1,19 s Nowe dekodowanie binarne: 0,67 s

Nowy format jest szybszy zarówno w kodowaniu, jak i dekodowaniu.

Format binarny jest większy niż JSON czy HTML. Zajmuje około dwa razy więcej miejsca niż JSON. Ponieważ korzystamy z renderowania po stronie serwera (server-side rendering), ten wzrost objętości nie wpływa na naszą wydajność.

Ten kompromis jest tego wart. Możemy teraz zmieniać linki i czyścić HTML za pomocą prostych, szybkich funkcji.

Jeśli budujesz własny format, napisz jasną specyfikację. Będziesz jej potrzebować, gdy wrócisz do kodu w przyszłości.

Źródło: https://dev.to/tomj/i-replaced-json-with-a-custom-binary-format-in-php-mok