Ich habe ein altes PHP-Skript von mir gegen die neuere, schickere Django-Version und die PHP-Version, mit vollem Ausspucken von HTML und alles funktionierte schneller. VIEL schneller bis zu dem Punkt, dass auf dem Django etwas nicht stimmt.Django (?) Wirklich langsam mit großen Datensätzen nach einigen Python-Profiling
Zuerst einige Kontext: Ich habe eine Seite, die Berichte über Verkaufsdaten ausspuckt. Die Daten können nach einer Anzahl von Dingen gefiltert werden, werden jedoch meistens nach Datum gefiltert. Dies macht es ein wenig schwierig, es zu cachen, da die Möglichkeiten für Ergebnisse fast endlos sind. Es gibt viele Zahlen und Berechnungen, aber es war nie ein Problem innerhalb von PHP.
UPDATES:
Nach einigen weiteren Tests nichts in meiner Sicht gibt es, dass die Verlangsamung verursacht. Wenn ich die Daten einfach nummeriere und 5 Zeilen gerenderten HTML ausspucke, ist es nicht so langsam (immer noch langsamer als PHP), aber wenn ich viele Daten rendere, ist es SEHR langsam.
Immer wenn ich einen großen Bericht (z. B. alle Verkäufe für das Jahr) ausgeführt habe, geht die CPU-Auslastung des Systems zu 100%. Ich weiß nicht, ob das viel bedeutet. Ich benutze mod_python und Apache. Vielleicht kann der Wechsel zu WSGI helfen?
Meine Vorlage-Tags, die die Zwischensummen/Gesamtwerte zwischen 0,1 Sekunden und 1 Sekunde für wirklich große Mengen anzeigen. Ich rufe sie etwa 6 Mal innerhalb des Berichts an, also scheinen sie nicht das größte Problem zu sein.
Nun lief ich ein Python-Profiler und kam mit diesen Ergebnissen zurück:
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 oben kommt, die einen Sinn machen kann, wie ich eine Menge Nummer tue Formatierung . Decimal.py macht Sinn, da der Bericht im Wesentlichen zu 90% nummeriert ist. Ich habe keine Ahnung, was die eingebaute Methode match
ist, da ich keine Regex oder ähnliches in meinem eigenen Code mache (Etwas, was Django macht?) Das nächste ist, dass ich itertools ifilter verwende.
Es scheint, dass diese die Hauptschuldigen sind und wenn ich herausfinden könnte, wie man die Bearbeitungszeit jener verringert, dann hätte ich eine viel viel schnellere Seite.
Hat jemand irgendwelche Vorschläge, wie ich anfangen könnte, dies zu reduzieren? Ich weiß nicht wirklich, wie ich das Problem mit Tokenize/Decimal lösen würde, ohne es einfach zu entfernen.
Update: Ich habe einige Tests mit/ohne Filter auf den meisten Daten durchgeführt und die Ergebniszeiten sind ziemlich gleich geblieben, wobei letzteres ein bisschen schneller ist, aber nicht viel, um die Ursache des Problems zu sein. Was genau passiert in tokenize.py?
Es ist unmöglich, etwas Nützliches ohne Ihre Ansicht Code und Profiling Anleitung vorschlagen. –
Alex: Meine Sicht ist ziemlich einfach. Es wird eine erste Liste mit Einträgen angezeigt. Wenn der Bericht geändert wird, werden einige Filter hinzugefügt. Das ist es wirklich. Meine Vorlage gruppiert das Dataset dann in zwei Abschnitte und führt dann einen Rundlauf durch alle durch und ruft templatetags auf dem Weg auf. (Aber ich habe die Template-Tags in 0.1 -> 0.5 Sekunden getaktet. Diese Templatetags sind die Zwischensummen/Summen des Berichts so dass die Ausführungszeit bei großen Datenmengen in Ordnung ist.) – Bartek
@Bartek: Bitte kommentieren Sie nicht Ihre eigene Frage. Es ist Ihre Frage, Sie können es aktualisieren, um alle relevanten Fakten zu enthalten. –