Django (?) Очень медленно работает с большими наборами данных после некоторого профилирования Python
Я сравнивал мой старый PHP-скрипт с более новой, более красивой версией Django и PHP, с полным выплевыванием из HTML, и все работало быстрее. Гораздо быстрее, до такой степени, что что-то должно быть не так с Джанго.
Сначала немного контекста: у меня есть страница, на которой выкладываются отчеты о продажах. Данные могут быть отфильтрованы по ряду вещей, но в основном фильтруются по дате. Это немного затрудняет кеширование, поскольку возможности для результатов практически безграничны. Было сделано много цифр и вычислений, но в PHP это никогда не было большой проблемой.
ОБНОВЛЕНИЕ:
After some additional testing there is nothing within my view that is causing the slowdown. If I am simply number-crunching the data and spitting out 5 rows of rendered HTML, it's not that slow (still slower than PHP), but if I am rendering a lot of data, it's VERY slow.
Whenever I ran a large report (e.g. all sales for the year), the CPU usage of the machine goes to 100%. Don't know if this means much. I am using mod_python and Apache. Perhaps switching to WSGI may help?
My template tags that show the subtotals/totals process anywhere from 0.1 seconds to 1 second for really large sets. I call them about 6 times within the report so they don't seem like the biggest issue.
Теперь я запустил профилировщик Python и вернулся с этими результатами:
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 выходит на первое место, что может иметь некоторый смысл, так как я много занимаюсь форматированием чисел. Decimal.py имеет смысл, так как отчет по существу состоит из 90% чисел. Понятия не имею, что такое встроенный методmatch
как я не использую Regex или что-то подобное в своем собственном коде (что-то делает Django?). Самое близкое, что я использую itertools ifilter.
Похоже, это главные виновники, и если бы я мог понять, как сократить время их обработки, то у меня была бы намного более быстрая страница.
У кого-нибудь есть какие-либо предложения о том, как я мог бы начать сокращать это? Я на самом деле не знаю, как бы я решил эту проблему с токенизацией / десятичной разметкой, не просто удаляя их.
Обновление: я выполнил некоторые тесты с / без фильтров на большинстве данных, и результаты в целом вернулись к тому же результату, последний был немного быстрее, но не стал причиной проблемы. Что именно происходит в tokenize.py?