Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> Lord, Striming XML vs JSON
Lord
post 12.09.2017, 18:49:23
Post #1





Grupa: Zarejestrowani
Postów: 239
Pomógł: 32
Dołączył: 10.03.2004

Ostrzeżenie: (10%)
X----


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-streamer

a Json

https://github.com/pcrov/JsonReader

i 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 ;(

  1. $stream = fopen($file->getRealPath(), "rb");
  2.  
  3. $reader = new JsonReader();
  4. $reader->stream($stream);
  5.  
  6. /*
  7.   * Wczytywanie obiektu
  8.   * $record - pojedyńczy record najwyższego poziomu w json
  9.   * $tree - przechowuje zagnieżdżenie elementu w strukturze, indeksy poszczególnych rekordów.
  10.   * $tmp - tablica do której zapisujemy dany poziom struktury rekordu json
  11.   * $depth - level na którym sa itemy;
  12.   */
  13.  
  14. $record = [];
  15. $tree = [];
  16. $tmp = &$record;
  17. $depth = 1;
  18.  
  19. /*
  20.   * Wczytywanie elementów json, zakonczyć gdy otrzymamy pełny jeden wpis.
  21.   * $record ma mieć formę tablicy asocjacyjnej.
  22.   */
  23.  
  24. while ($reader->read()) {
  25.  
  26. switch ($reader->type()) {
  27. /*
  28.   * Początek obiektu lub tablicy
  29.   */
  30. case JsonReader::OBJECT :
  31. case JsonReader::ARRAY :
  32. /*
  33.   * Jeżeli mamy pusty index to okręślamy go na podstawie ostatniego zapisanego elementu w $tree
  34.   */
  35. if ($reader->depth() > $depth) {
  36. if (empty($reader->name())) {
  37. $tree[] = ($c = count($tmp) > 0) ? $c : 0;
  38. $tmp = &$tmp[end($tree)];
  39. } else {
  40. $tree[] = $reader->name();
  41. $tmp = &$tmp[$reader->name()];
  42. }
  43.  
  44. $tmp = [];
  45. }
  46. break;
  47.  
  48. /*
  49.   * Koniec obiektu lub tablicy
  50.   */
  51. case JsonReader::END_OBJECT :
  52. case JsonReader::END_ARRAY :
  53. /*
  54.   * Jeżeli obiekt lub tablica się zakończyli musimy wrócić do wcześniejszego
  55.   * elementu w strukturze
  56.   */
  57.  
  58. if ($reader->depth() > $depth) {
  59. $tmp = &$record;
  60. if (count($tree) > 0) {
  61. array_pop($tree);
  62. foreach ($tree as $item) {
  63. $tmp = &$tmp[$item];
  64. }
  65. }
  66.  
  67. } elseif ($reader->depth() == $depth) {
  68. dump($tmp);
  69. $record = [];
  70. $tmp = &$record;
  71. }
  72. break;
  73. /*
  74.   * Pojedynczy element
  75.   */
  76. default :
  77. /*
  78.   * Jeżeli indeks jest pusty (np. ["a", 1, "b", 2])
  79.   * dodajemy element przez array_push
  80.   * w przeciwnym razie
  81.   * dołączamy nowy wpis przez array_merge
  82.   */
  83. if ($reader->depth() > $depth) {
  84. if (empty($reader->name())) {
  85. array_push($tmp, $reader->value());
  86. } else {
  87. $tmp = array_merge($tmp, [$reader->name() => $reader->value()]);
  88. }
  89. }
  90. }
  91.  
  92. }
  93.  
  94. $reader->close();
  95. fclose($stream);


Witam wink.gif
czy ja zle zadaje pytania? bo moje tematy zawsze bez odpowiedzi tongue.gif

Czego używacie do wczytywania dużych (~200MB ) plików JSON smile.gif ?

Ten post edytował Lord 12.09.2017, 12:16:28
Go to the top of the page
+Quote Post
sabat24
post 12.09.2017, 20:26:13
Post #2





Grupa: Zarejestrowani
Postów: 175
Pomógł: 26
Dołączył: 13.09.2007
Skąd: Gdańsk

Ostrzeżenie: (0%)
-----


Ja używałem swego czasu tego: https://github.com/MAXakaWIZARD/JsonCollectionParser
Ze 160 MB sobie radził.
Go to the top of the page
+Quote Post
Lord
post 12.09.2017, 23:54:12
Post #3





Grupa: Zarejestrowani
Postów: 239
Pomógł: 32
Dołączył: 10.03.2004

Ostrzeżenie: (10%)
X----


Cytat(sabat24 @ 12.09.2017, 21:26:13 ) *
Ja używałem swego czasu tego: https://github.com/MAXakaWIZARD/JsonCollectionParser
Ze 160 MB sobie radził.


Ten też sobie radzi, ale tylko o ile wczytanie 1000 rekordów xml zajmuje mi Time 0.31s a JSON Time 9.34s. tongue.gif
Go to the top of the page
+Quote Post
Crozin
post 13.09.2017, 07:03:45
Post #4





Grupa: Zarejestrowani
Postów: 6 476
Pomógł: 1306
Dołączył: 6.08.2006
Skąd: Kraków

Ostrzeżenie: (0%)
-----


Tutaj niestety wychodzi porównanie wydajności pomiędzy kodem napisanym w C + PHP (wbudowany moduł od obsługi XML w C wykorzystywany przez API w PHP) konta czyste PHP. Co tu dużo mówić, PHP jest wolny. Co możesz zrobić?
1. Upewnij się, że korzystasz z PHP 7.x nie 5.x - jest zauważalnie szybszy, ale na pewno nie zniweluje Ci to różnicy.
2. Poszukaj jakiegoś prasera, który został napisany jako moduł w C dla PHP. Wtedy powinieneś uzyskać czasy takie jak w przypadku XML-a. Przy czym nie mam pojęcia czy takowy istnieje.
3. To już jest obejście, nie rozwiązanie problemu:
3.a. Przy pomocy zewnętrznego, wydajnego softu konwertuj sobie JSON do XML przed przetworzeniem.
3.b. W ogóle skorzystaj z innej platformy.

Go to the top of the page
+Quote Post
sabat24
post 13.09.2017, 07:08:11
Post #5





Grupa: Zarejestrowani
Postów: 175
Pomógł: 26
Dołączył: 13.09.2007
Skąd: Gdańsk

Ostrzeżenie: (0%)
-----


Powyższa biblioteka daje lepsze czasy, ale moim zdaniem nie jesteś w stanie zejść poniżej paru sekund w czystym php. Rozwiązaniem porównywalnym do tego z XML jest albo odpalenie parserów w pytonie albo doinstalowanie specjalnych bibliotek do Apacha. Tego ostatniego nie próbowałem, ale jak szukałem dla siebie rozwiązań, było kilka polecanych z rok temu, które ponoć dawały dobre wyniki.
Go to the top of the page
+Quote Post
Lord
post 13.09.2017, 13:00:38
Post #6





Grupa: Zarejestrowani
Postów: 239
Pomógł: 32
Dołączył: 10.03.2004

Ostrzeżenie: (10%)
X----


Dziekuję za pomoc. Myślałem, że takie wyniki nie są akceptowalne, ale skoro to norma to lecimy dalej ...
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Wersja Lo-Fi Aktualny czas: 28.03.2024 - 09:22