Django (?) Realmente lento con grandes conjuntos de datos después de hacer un perfil de python

Estaba comparando un antiguo script PHP en comparación con la versión más nueva y elegante de Django y la de PHP, con un escupido completo de HTML y todo funcionaba más rápido. Mucho más rápido hasta el punto de que algo tiene que estar mal en el Django.

Primero, algo de contexto: tengo una página que distribuye informes de datos de ventas. Los datos se pueden filtrar por varias cosas, pero en su mayoría se filtran por fecha. Esto hace que sea un poco difícil almacenarlo en caché ya que las posibilidades de resultados son casi infinitas. Hay muchos números y cálculos realizados, pero nunca fue un problema manejar dentro de PHP.

ACTUALIZACIONES:

Después de algunas pruebas adicionales, no hay nada en mi opinión que esté causando la desaceleración. Si simplemente hago un cálculo numérico de los datos y escupo 5 filas de HTML renderizado, no es tan lento (aún más lento que PHP), pero si estoy generando una gran cantidad de datos, es MUY lento.

Cada vez que ejecuté un informe grande (por ejemplo, todas las ventas del año), el uso de la CPU de la máquina es del 100%. No sé si esto significa mucho. Estoy usando mod_python y Apache. Tal vez el cambio a WSGI puede ayudar?

Las etiquetas de mi plantilla que muestran los subtotales / totales se procesan en cualquier lugar desde 0,1 segundos hasta 1 segundo para conjuntos realmente grandes. Los llamo aproximadamente 6 veces en el informe para que no parezcan ser el mayor problema.

Ahora, ejecuté un perfilador de Python y regresé con estos resultados:

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 aparece en la parte superior, lo que puede tener algún sentido ya que estoy haciendo mucho formato de números. Decimal.py tiene sentido ya que el informe es esencialmente un 90% de los números. No tengo ni idea de cuál es el método incorporado.match es como no estoy haciendo ningún Regex o similar en mi propio código (¿Algo que está haciendo Django?) Lo más cercano es que estoy usando itertools ifilter.

Parece que esos son los principales culpables y si pudiera averiguar cómo reducir el tiempo de procesamiento de esos, entonces tendría una página mucho más rápida.

¿Alguien tiene alguna sugerencia sobre cómo podría comenzar a reducir esto? Realmente no sé cómo arreglaría esto los problemas de tokenize / decimal sin simplemente eliminarlos.

Actualización: realicé algunas pruebas con / sin filtros en la mayoría de los datos y los tiempos de resultados prácticamente volvieron a ser lo mismo, siendo este último un poco más rápido pero no mucho para ser la causa del problema. ¿Qué está pasando exactamente en tokenize.py?

Respuestas a la pregunta(4)

Su respuesta a la pregunta