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?

Ответы на вопрос(4)

Ваш ответ на вопрос