Pisałem apkę do wczytywania dużych plików XML i JSON do bazy i mam pewien problem
mam 2 pliki jeden z tymi samymi danymi i do wczytywania XML używam
https://github.com/prewk/xml-string-streamera Json
https://github.com/pcrov/JsonReaderi okazuje się, że wczytywanie Json trwa x100 wolniej ;(
sprawdzałem xdebug profilerem (o ile to dobrze zrobiłem) to za wolne działanie odpowiada ta class JsonReader.
Mój kod. Co robię nie tak ;(
$stream = fopen($file->getRealPath(), "rb");
$reader = new JsonReader();
$reader->stream($stream);
/*
* Wczytywanie obiektu
* $record - pojedyńczy record najwyższego poziomu w json
* $tree - przechowuje zagnieżdżenie elementu w strukturze, indeksy poszczególnych rekordów.
* $tmp - tablica do której zapisujemy dany poziom struktury rekordu json
* $depth - level na którym sa itemy;
*/
$record = [];
$tree = [];
$tmp = &$record;
$depth = 1;
/*
* Wczytywanie elementów json, zakonczyć gdy otrzymamy pełny jeden wpis.
* $record ma mieć formę tablicy asocjacyjnej.
*/
while ($reader->read()) {
switch ($reader->type()) {
/*
* Początek obiektu lub tablicy
*/
case JsonReader::OBJECT :
/*
* Jeżeli mamy pusty index to okręślamy go na podstawie ostatniego zapisanego elementu w $tree
*/
if ($reader->depth() > $depth) {
if (empty($reader->name())) { $tree[] = ($c = count($tmp) > 0
) ?
$c : 0; $tmp = &$tmp[end($tree)]; } else {
$tree[] = $reader->name();
$tmp = &$tmp[$reader->name()];
}
$tmp = [];
}
break;
/*
* Koniec obiektu lub tablicy
*/
case JsonReader::END_OBJECT :
case JsonReader::END_ARRAY :
/*
* Jeżeli obiekt lub tablica się zakończyli musimy wrócić do wcześniejszego
* elementu w strukturze
*/
if ($reader->depth() > $depth) {
$tmp = &$record;
foreach ($tree as $item) {
$tmp = &$tmp[$item];
}
}
} elseif ($reader->depth() == $depth) {
dump($tmp);
$record = [];
$tmp = &$record;
}
break;
/*
* Pojedynczy element
*/
default :
/*
* Jeżeli indeks jest pusty (np. ["a", 1, "b", 2])
* dodajemy element przez array_push
* w przeciwnym razie
* dołączamy nowy wpis przez array_merge
*/
if ($reader->depth() > $depth) {
if (empty($reader->name())) { } else {
$tmp = array_merge($tmp, [$reader->name() => $reader->value()]); }
}
}
}
$reader->close();
Witam
czy ja zle zadaje pytania? bo moje tematy zawsze bez odpowiedzi
Czego używacie do wczytywania dużych (~200MB ) plików JSON

?
Ten post edytował Lord 12.09.2017, 12:16:28