Prosty pająk sieciowy, czyli parsowanie stron internetowych, część 2

February 1, 2012
By

This post was kindly contributed by SmarterPoland » R - go there to comment and to read the full post.

Jakiś czas temu we wpisie ,,Prosty pająk sieciowy‘’ (link tutaj) przedstawiłem połączenie skryptu w Perlu i skryptu w R, które wykorzystywałem do zbierania danych o samochodach z serwisu otomoto.pl.

W komentarzach do wpisu użytkownik Maciej opisał podobne rozwiązanie, ale zamiast skryptu w Perlu wykorzystujące pakiet XML (dostępny dla programu R w repozytorium CRAN). Rozwiązanie Maćka ma kilka zalet nad hybryda R+Perl, z mojego punktu widzenia, największa zaleta jest taka, że ,,wszystko’’ dzieje się w R. Łatwiej utrzymać, przenosić i rozwijać rozwiązanie, które jest bardziej jednolite.

Spodziewany koszt tej jednolitości to czasu działania. Wydawało (mi) się, że Perl jako narzędzie do przetwarzania tekstów i działania na stronach internetowych powinien być szybszy od R. Pytanie jaka będzie różnica w czasach działania?

Maciej Beręsewicz przygotował dwa skrypty w R, które wykonują praktycznie te same operacje co mój skrypt w Perlu. Pierwszy skrypt (wersjaStrsplitMB.R) wykorzystuje funkcję getURL() aby ściągnąć źródła strony a następnie używa funkcji strsplit() by wydobyć ze źródła HTML interesujące rzeczy. Drugi skrypt (wersjaXMLMB.R) wykorzystuje funkcję htmlParse() od odczytania i parsowania dokumentu HTML, a następnie xpathApply() do operacji na przetworzonym wstępnie dokumencie. Oba skrypty są dostępne w tym katalogu.

 

Aby porównać czasy działania uruchomiłem te trzy wersje (Perl, R z strsplit i R z XML) kilkukrotnie. Za każdym razem ściągając informacje o 4 tyś aut. Testy rożnych rozwiązań odbyły się na tej samej maszynie, na szerokopasmowym łączu (wykorzystywany tylko jeden węzeł  o wydajności odpowiadającej intel i7). Testy wykonałem o różnych godzinach by zobaczyć jak wpływ na czasy będzie miało natężenie ruchu w sieci, ale koniec końców otrzymałem bardzo powtarzalne wyniki, bez względu na godzinę czy dzień wykonania testów. Więc niżej pokażę tylko medianowe wyniki  z różnych uruchomień.

Porównywane wersje:

  • Wersja P = Perl + wczytanie danych do R
  • Wersja R1 = R ściąganie getURL() i parsowanie z użyciem funkcji strsplit()
  • Wersja R2 = R ściąganie i parsowanie z użyciem funkcji htmlParse()

Medianowe czasy działań i odpowiadająca im wydajność liczna w liczbie ,,przetworzonych’ ‘stron opisujących kolejne auta na sekundę

 

Wersja testowana    Wydajność               Czas pobierania
                    liczona aut/sec         i przetwarzania 4tys aut

Wersja P            4.61 aut/sec            867 sekund ( < 15 min)
Wersja R1           2.93 aut/sec           1365 sekund ( < 23 min)
Wersja R2           4.19 aut/sec            954 sekund ( < 16 min)

 

Ponieważ profilowanie kodu w R jest cudownie proste sprawdziłem też, które elementy ,,zżerają’’ najwięcej czasu w obu wersja Rowych. Poniżej wyniki dla medianowego czasu działania (tylko operacje najbardziej czasochłonne)

Wersja R1
                        total.time  total.pct
getURL                      714.08      52.53
strsplit                    633.30      46.58

Wersja R2
                        total.time  total.pct
htmlParse                   919.01      96.21

W wersji R1, ponad 99% czasu zużyte jest te dwie operacje. Dodatkowy narzut związany z pętlami, zapisywaniem na dysku itp to mniej niż 1%. Z tych dwóch operacji mniej więcej tyle samo czasu trwa odczytywanie HTML przez sieć co jego parsowanie.

W wersji R2 większość czasu przetwarzania to wywołanie htmlParse(), która jest opakowaniem odwołania do funkcji napisanej w C.

 

Pointa?

Wersja perlowa jest najszybsza, ale wersja używająca pakietu XML jest niewiele wolniejsza. Biorąc pod uwagę dodatkowo długość kodu, jednolitość bardziej podoba mi się rozwiązanie Macka używające pakietu XML.

 

Tags: , , , , ,

Comments are closed.