Ukládání dat do PHP, JSON a NEON souborů
28. června 2013
V souvislosti s tvorbou InnuDb jsem zkoušel uložit data (pole) do různých formátů a sledoval jsem, jak dlouho trvá načtení dat zpět a kolik tyto soubory ve výsledku zabírají místa na disku.
Příprava
Připravil jsem si tedy 2 skripty – jeden skript mi vygeneroval pole s daty a pak toto pole uložil do 5 různých souborů. Druhý skript mi tato data načetl zpět.
- JSON – data se uložila do jednoho dlouhého
souvislého řádku v následující podobě:
{"key":{"subkey":"value","subkey2":"value2",...},"key2":...,...}
- NEON –
výstup byl podobný jako v případě JSON, jediným rozdílem byly
chybějící uvozovky kolem názvů klíčů a přidaná mezera za každou
dvojtečkou a čárkou:
{key: {subkey: "value", subkey2: "value2",...}, key2: ..., ...}
- NEON –
další soubor byl opět ve formátu NEON, nyní
byla ale při ukládání dat do souboru použita volba
Neon::BLOCK
, takže výstup vypadal tak, jak asi NEON nejvíc znáte:key: subkey: "value" subkey2: "value2" ... key2: ... ...
- PHP
pole – dalším formátem byl tradiční PHP soubor, který vracel pole
(
$pole = include 'soubor-s-polem.php';
). Tento výstup jsem poté ještě prohnal filtrem, který z něho vypustil přebytečné mezery apod.:<?php return array('key'=>array('subkey'=>"value",'subkey2'=>"value2",...),'key2'=>...,...);
- Serializované
PHP pole – poslední varianta využila PHP funkci
serialize()
, které bylo předáno pole s daty a její výstup byl poté uložen do souboru.
Do souborů se ukládalo asociativní pole o 100 klíčích, pod každým klíčem bylo uchováno další asociativní pole o dalších 100 klíčích (a 100 hodnotách). Velikosti výsledných souborů byly následující (seřazeno od datově nejmenších po největší):
# | Formát | Velikost na disku |
---|---|---|
1–2. | NEON | 319 790 bajtů |
1–2. | Neon::BLOCK | 319 790 bajtů |
3. | JSON | 319 891 bajtů |
4. | PHP soubor | 330 611 bajtů |
5. | serialize() | 380 898 bajtů |
Oba
soubory s NEONem měly stejnou velikost, což by se pravděpodobně změnilo ve
chvíli, kdy by byly použity více zanořená pole (u Neon::BLOCK
by se muselo použít více tabulátorů). NEON a JSON jsou na tom skoro
nastejno, i když NEON vychází ze souboje s o pár bajtů lepším skóre.
Rozdíl by se samozřejmě zvětšil s větším objemem dat.
Následuje
PHP soubor s polem. Tady by se dalo několik dalších bajtů ušetřit, pokud
by se místo konstrukce array()
, použily hranaté závorky
[]
(dostupné od PHP 5.4). Na posledním místě stojí soubor se
serializovaným polem – zde se žádné bajty ušetřit
nedají.
Rychlost načtení
A jak je to při načítání dat? Načítací skript zkusil každý soubor 100× načíst z disku a zpracovat do podoby pole. Výsledky byly následující:
# | Formát | Průměrný čas (s) |
---|---|---|
1. | serialize() | 01.231801589 |
2. | JSON | 01.562570254 |
3. | PHP soubor | 02.110288699 |
4. | NEON | 75.669364055 |
5. | Neon::BLOCK | 87.711379369 |
Teď
se nám to pořadí celkem otočilo, co? :D Nejvíce zaostává NEON. To je
pravděpodobně způsobeno tím, že všechny ostatní funkce (JSON,
serialize()
,…) jsou na rozdíl od metody pro dekódování NEONu
přímo součástí jádra PHP. Takový rozdíl se někde
projevit musí.
Výsledek
Z celého měření tak jako vítěz vychází soubor s daty ve formátu JSON, který patřil mezi datově nejmenší a zároveň nejrychleji zpracované soubory. Budiž mu to přáno :)