Django (?) Naprawdę spowalnia z dużymi zestawami danych po wykonaniu profilowania Pythona
Porównywałem stary mój skrypt PHP z nowszym, bardziej wyszukanym wersją Django i PHP, z pełnym wypluwaniem HTML i wszystko działało szybciej. DUŻO szybciej, że coś musi być nie tak w Django.
Po pierwsze, jakiś kontekst: mam stronę, która wypluwa raporty o danych sprzedaży. Dane mogą być filtrowane przez wiele rzeczy, ale są przeważnie filtrowane według daty. To sprawia, że trochę trudno jest ją buforować, ponieważ możliwości uzyskania wyników są prawie nieograniczone. Wykonano wiele liczb i obliczeń, ale nigdy nie było problemu z obsługą PHP.
AKTUALIZACJE:
Po kilku dodatkowych testach nie ma nic, co spowodowałoby spowolnienie. Jeśli po prostu przetwarzam dane liczbowo i wypluwam 5 wierszy renderowanego HTML, nie jest to tak powolne (wciąż wolniejsze niż PHP), ale jeśli renderuję dużo danych, jest to BARDZO powolne.
Za każdym razem, gdy uruchamiałem duży raport (np. Cała sprzedaż za dany rok), użycie procesora przez maszynę wynosi 100%. Nie wiem, czy to dużo znaczy. Używam mod_python i Apache. Może przejście na WSGI może pomóc?
Moje znaczniki szablonów, które pokazują proces sum częściowych / sumarycznych od 0,1 sekundy do 1 sekundy dla naprawdę dużych zestawów. Dzwonię do nich około 6 razy w raporcie, więc nie wydają się największym problemem.
Teraz uruchomiłem profilera Pythona i wróciłem z następującymi wynikami:
Ordered by: internal time List reduced from 3074 to 20 due to restriction ncalls tottime percall cumtime percall filename:lineno(function) 2939417 26.290 0.000 44.857 0.000 /usr/lib/python2.5/tokenize.py:212(generate_tokens) 2822655 17.049 0.000 17.049 0.000 {built-in method match} 1689928 15.418 0.000 23.297 0.000 /usr/lib/python2.5/decimal.py:515(__new__) 12289605 11.464 0.000 11.464 0.000 {isinstance} 882618 9.614 0.000 25.518 0.000 /usr/lib/python2.5/decimal.py:1447(_fix) 17393 8.742 0.001 60.798 0.003 /usr/lib/python2.5/tokenize.py:158(tokenize_loop) 11 7.886 0.717 7.886 0.717 {method 'accept' of '_socket.socket' objects} 365577 7.854 0.000 30.233 0.000 /usr/lib/python2.5/decimal.py:954(__add__) 2922024 7.199 0.000 7.199 0.000 /usr/lib/python2.5/inspect.py:571(tokeneater) 438750 5.868 0.000 31.033 0.000 /usr/lib/python2.5/decimal.py:1064(__mul__) 60799 5.666 0.000 9.377 0.000 /usr/lib/python2.5/site-packages/django/db/models/base.py:241(__init__) 17393 4.734 0.000 4.734 0.000 {method 'query' of '_mysql.connection' objects} 1124348 4.631 0.000 8.469 0.000 /usr/lib/python2.5/site-packages/django/utils/encoding.py:44(force_unicode) 219076 4.139 0.000 156.618 0.001 /usr/lib/python2.5/site-packages/django/template/__init__.py:700(_resolve_lookup) 1074478 3.690 0.000 11.096 0.000 /usr/lib/python2.5/decimal.py:5065(_convert_other) 2973281 3.424 0.000 3.424 0.000 /usr/lib/python2.5/decimal.py:718(__nonzero__) 759014 2.962 0.000 3.371 0.000 /usr/lib/python2.5/decimal.py:4675(__init__) 381756 2.806 0.000 128.447 0.000 /usr/lib/python2.5/site-packages/django/db/models/fields/related.py:231(__get__) 842130 2.764 0.000 3.557 0.000 /usr/lib/python2.5/decimal.py:3339(_dec_from_triple)
tokenize.py wychodzi na wierzch, co może mieć jakiś sens, ponieważ wykonuję wiele formatowania liczb. Decimal.py ma sens, ponieważ raport ma zasadniczo 90% liczb. Nie mam pojęcia, co to jest wbudowana metodamatch
jest tak, jak nie robię żadnego Regexa lub podobnego w moim własnym kodzie (coś, co robi Django?) Najbliższą rzeczą jest użycie itertools ifilter.
Wygląda na to, że są to główni winowajcy, a gdybym mógł dowiedzieć się, jak skrócić czas przetwarzania tych, to miałbym znacznie szybszą stronę.
Czy ktoś ma jakieś sugestie na temat tego, jak mogę zacząć redukować to? Naprawdę nie wiem, jak to naprawić problemy z tokenize / dziesiętnym bez ich usuwania.
Aktualizacja: Przeprowadziłem kilka testów z / bez filtrów na większości danych, a czasy wyników wróciły prawie tak samo, przy czym ten drugi był nieco szybszy, ale nie za bardzo, aby być przyczyną problemu. Co dokładnie dzieje się w tokenize.py?