Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> DOMDocument::load() kontra XMLReader::open(), Wydajność i zużycie pamięci.
kreatiff
post 2.08.2019, 18:18:23
Post #1





Grupa: Zarejestrowani
Postów: 324
Pomógł: 105
Dołączył: 7.08.2012

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


Do teraz byłem pewny, że XMLReader bije na głowę DOMDocument wydajnością (zużycie pamięci oraz prędkość w przeszukiwaniu pliku XML).

A dzisiaj zrobiłem sobie test. Powiedzmy, że interesuje mnie wyciągnięcie z pliku XML (jego sposób generowania poniżej) tylko elementów path, których wartość zawiera ciąg 'song1000'.
  1. $dom = new DOMDocument;
  2. $dom->load('test.xml');
  3.  
  4. $xpath = new DOMXpath($dom);
  5. $q = $xpath->query('/xml/track/path[contains(text(), "song1000")]');
  6. foreach ($q as $a ){
  7. echo $a->nodeValue . '<br>';
  8. }

kontra
  1. $xml = new XMLReader;
  2. $xml->open('test.xml');
  3. while($xml->read()) {
  4. if ($xml->name === 'path' && $xml->nodeType == XMLReader::ELEMENT) {
  5. $xml->read();
  6. if (strpos($xml->value, 'song1000') !== false) echo $xml->value . '<br>';
  7. }
  8. };

Plik XML (kradziony ze Stacka):
  1. $xml = new SimpleXMLElement('<xml/>');
  2. for ($i = 1; $i <= 33000; ++$i) {
  3. $track = $xml->addChild('track');
  4. $track->addChild('path', "song$i.mp3");
  5. $track->addChild('title', "Track $i - Track Title");
  6. }
  7. file_put_contents('test.xml', $xml->asXML());

Tak wygenerowany plik ma kilka megabajtów.

I... DOMDocument jest pomijanie lepszy, ale można założyć, że nie ma większej różnicy w obu przypadkach.
A jak tylko zamienię sposób dobierania się do pliku XML przez DOMDocument na $dom->loadXML(file_get_contents('test.xml'));, to już zużycie pamięci idzie w megabajty. I dopiero tutaj wygląda to jak ładowanie całego pliku do pamięci wyglądać powinno.

Poszedłem dalej i zrobiłem plik XML ważący 160 mega (2 miliony iteracji pętli, przy tworzeniu pliku jak wyżej).
Tutaj już XMLReader okazał się lepszy. Czasowo 15 setnych szybciej (ale czasy wykonania skryptu są rzędu niecałych 5 sekund) i o niecałe 100 kilobajtów mniejsze zużycie pamięci (DOMDocument to 502 kilobajty, XMLReader - 420 kilobajtów).

Czyli, wyszło mi, że przy mniejszych plikach nawet lepiej używać DOMDocument, bo jest łatwiejszy w obsłudze, parsowaniu, wyszukiwaniu danych, bo mam DOMXPath zaimplementowany. Dopiero przy większych plikach XMLReader zaczyna przodować, ale jednak ciągle różnice nie są jakieś znaczące.

Coś robię źle? Może ten przykład jest za prosty, by uwidocznić miażdżącą przewagę XMLReadera nad DOMDocument?
A może tak to działa i można z czystym sumieniem używać DOMDocument nawet do kilkusetmegabajtowych plików?

EDYCJA:
W sumie znalazłem odpowiedź.
To na czym najbardziej mi zależało (możliwość łatwego, kilkukrotnego odpytywania przy pomocy XPath) uwidoczniło, że jednak jak chcemy kilka różnych zapytań do pliku XML, to działanie skryptu zaczyna się dość mocno wydłużać w czasie (co logiczne, ale mnie zaskoczyło, że aż tak bardzo, wyglada jakby za każdym zapytaniem plik skanowany był na nowo i nie ma żadnego nie wiem cachowania czy coś). Tylko jednorazowe użycie XPath może konkurować z tym samym w XMLReader.
DOMDocument, by pozostał skanowany tylko raz, musiałoby chyba być odpytany jakimś dość skomplikowanym, pojedynczym zapytaniem XPath (by tylko raz skanować plik, tak jak to się dzieje w XMLReader), ale takie coś pewnie oznaczałoby stosowanie warunków, by wyciągnięte dane jakoś segregować. To tak nieco podobnie jak przy XMLReader. O ile w ogóle byłoby możliwe.
Więc rzeczywiście mniej zasobożerny pozostanie XMLRader, którego działanie jest jednak dosć karkołomne i oznacza sporo dodatkowego kodu i warunków, by wyciągać interesujące nas dane.

Ten post edytował kreatiff 3.08.2019, 10:08:34
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: 25.04.2024 - 05:48