• Zwiększ rozmiar czcionki
  • Domyślny  rozmiar czcionki
  • Zmniejsz rozmiar czcionki
Home Artykuły .NET Wydajna paginacja przy użyciu XmlReadera

Wydajna paginacja przy użyciu XmlReadera

Email Drukuj PDF
Ocena użytkowników: / 3
SłabyŚwietny 

Właśnie przeczytałem sobie artykuł o paginacji (czyli dzieleniu listy wyników na strony) na wortalu XMLguru.net (artykuł opisuje w jaki sposób wykorzystać do paginacji arkusz Xslt), który skłonił mnie do pewnych przemyśleń. Wyszło mi coś takiego... Przetwarzanie dokumentów Xmlowych za pomocą Xslt jak najbardziej. Natomiast sama paginacja już chyba nie - bo można to zrobić o wiele wydajniej bez Xslt. Jak ? Zacznijmy po kolei.

Paginacja to w zasadzie dwie rzeczy
- wyświetlenie strony z wynikami dla wybranego numeru strony
- wyświetlenie linków umożliwiających nawigację pomiędzy stronami

Kilka spostrzeżen:
- zazwyczaj pokazujemy x rekordów gdzie x jest znacząco mniejsze niż liczba wszystkich rekordów (np. 20 z 1000)
- zazwyczaj ludzie zainteresowani są pierwszymi kilkoma stronami które często stanowią mniej niż 10% wyników

Stąd można wysnuć następujący wniosek - transformacja całego dokumentu Xmlowego (wszystkie wyniki) tylko w celu pokazania malutkiej jego cząstki (bieżąca strona) to trochę marnotrastwo prądu ponieważ parsowanie i ładowanie dokumentu do tzw. Xml cache'u (czyli obiektu typu XmlDocument, XPathDocument czy XDocument) jest kosztowne zarówno jeśli chodzi o czas (parsowanie tekstu, czas potrzebny na alokację pamięci) jak i pamięć (średnio można przyjąć że obiekt Xml w pamięci potrzebuje pieć razy więcej pamięci niż jego rozmiar na dysku). O wiele lepiej by było wybrać w jak najmniej kosztowny sposób tylko te rekordy które chcemy pokazać i użyć je jako źródło dalszej transformacji. Na platformie .NET do efektywnego czytania dokumentów Xmlowych służy XmlReader.  Od strony technicznej - na platformie .NET - całe rozwiązanie mogłoby to wyglądać tak:

1) Wyświetlanie wyników:
Za pomocą XmlReadera przeskakujemy węzły ze stron poprzedzających stronę którą mamy wyświetlić. Po dojściu do strony którą mamy wyświetlić czytamy x rekordów, które ładujemy do Xml cache'a. To co załadujemy przetwarzamy za pomocą arkusza Xslt. (Zauważmy - zawsze to będzie jedna strona wyników). Tutaj wyświetlanie wyników łączy się z nawigacją
Jeśli nie musimy pokazywać PRECYZYJNIE nawigacji (dokładnie chodzi o rzeczywistą liczbę stron) kończymy czytanie. W ten sposób Xml cache będzie zawierał tylko to co ma być pokazywane (oszczędność przy parsowaniu dokumentu, oszczędność pamięci, bardziej efektywne przetwarzanie po stronie Xslt). Jeśli potrzebujemy rzeczywistą liczbę stron to czytamy pozostałe węzły po osi following-sibling (ale nie ładujemy do xml cache'a) tylko po to, żeby policzyć całkowitą liczbę rekordów.

2) Nawigacja:
Najczęściej ludzi nie interesuje pokazanie setek linków do poszczególnych stron. Z reguły +/- 2 strony wystarczają. Taką nawigację można wygenerować częściowo "na pałę" - zakładając optymistycznie, że są jakieś strony po aktualnie wyświetlanej. Jeśli użytkownik kliknie na stronę której tak naprawdę nie ma to pokazywana jest ostatnia strona z odpowiednio poprawioną nawigacją (przypomina zachowanie popularnych search engine'ów? - powinno...). Drobnym usprawnieniem jest sprawdzanie czy bieżąca strona nie jest ostatnią, i - jeśli akurat tak jest - nie wyświetlanie linków do kolejnych stron.
Jeśli trzeba pokazać wszystkie linki można próbować oszacować liczbę stron (dzielimy wielkość pliku przez wielkość rekordów do pokazania) - cały czas nie jest to dokładne ale powinno wystarczyć. Ostatnia możliwość to pokazanie wszystkiego "zgodnie z prawdą" - w tym przypadku musimy policzyć wszystkie rekordy czyli przejść przez caly dokument źródłowy.

Po dawce teorii, czas na praktykę. Listing 2 zawiera kod zwracający zadaną strone z dokumentu Xmlowego. Kod działa dla dokumentów, w których rekordy dzielone na strony znajdują się bezpośrednio pod elementem root (są jego bezpośrednimi dziećmi). Przykład takiego wejściowego dokumentu Xmlowego został przedstawiony na listingu 1.

Źródła są też dostępne do ściągnięcia tutaj.

Artykuł zamieszczono dzięki uprzejmości xml.com.pl

Poprawiony: wtorek, 19 maja 2009 09:15  
Komentarze (4)
1 sobota, 21 marca 2009 12:03
Przedstawiony pomysł też nie jest zły. Zresztą pomysłów na paginację będzie pewnie z milion. Różnica jest taka, że ja zarzynam pamięć, Ty procesor :)
2 poniedziałek, 23 marca 2009 03:23
Paweł Kadłuczka
Nie wiem jak jest na innych platformach ale na platformie .NET wszelkie czytanie dokumentów Xmlowych w przestrzeni nazw System.Xml - niezależnie od tego czy ładujemy arkusz xslt do obiektu klasy XslCompiledTransfrom czy jakiś dokument Xmlowy do obiektu klasy XmlDocument czy XPathDocument - zawsze jest realizowane za pomocą XmlReadera. Ktoś/coś musi po prostu tego Xmla sparsować i jest to właśnie XmlReader. Parafrazując: ja zarzynam procesor, Ty pamięć i procesor :)
Rozwiązanie z Xslt ma natomiast jedną niezaprzeczalną wadę [miało być "zaletę" (dodano: 3/24/09)] - jest o wiele prostsze i łatwiejsze w utrzymaniu przy dużych projektach ten koszt jest wymierny.

Dzięki za umieszczenie artykułu!
moozzyk
3 poniedziałek, 23 marca 2009 09:33
szomiz
Jeżeli łatwiejsze utrzymanie jest wadą, to zaczynam rozumieć dlaczego niektóre projekty (zwłaszcza dla administracji) kosztują tyle ile kosztują ;>

No to dorzucę jeszcze jedną "wadę". Transformacje to jeden z dwóch xml'owych standardów zaimplementowanych poprawnie i w całości przez wszystkich liczących się dostawców. Można dzięki temu przenosić rozwiązania między platformami z minimalnym nakładem kosztów.
4 środa, 25 marca 2009 05:08
Paweł Kadłuczka
No z tą wadą to pojechałem... Oczywiście miałem na myśli zaletę ;)

moozzyk

Dodaj swój komentarz

Imię:
Adres e-mail:
Strona WWW:
Treść (możesz używać HTML):
JoomlaWatch Stats 1.2.9 by Matej Koval

Użytkownicy

Naszą witrynę przegląda teraz 4 gości