Estaba comparando un antiguo script PHP versus la versión Django más nueva y lujosa y la versión PHP, con escupción completa 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.Django (?) Realmente lento con grandes conjuntos de datos después de hacer un perfil de python
Primero, algo de contexto: tengo una página que arroja informes de datos de ventas. Los datos se pueden filtrar por varias cosas, pero en su mayoría están filtrados por fecha. Esto hace que sea un poco difícil de almacenar en caché, ya que las posibilidades de resultados son casi infinitas. Hay muchos números y cálculos realizados, pero nunca fue un gran problema manejarlo dentro de PHP.
ACTUALIZACIONES:
Después de algunas pruebas adicionales que no hay nada dentro de mi opinión de que la causa de la desaceleración. Si simplemente estoy analizando los datos y escupiendo 5 filas de HTML renderizado, no es tan lento (aún más lento que PHP), pero si estoy procesando 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 cambiar a WSGI puede ayudar?
Mis etiquetas de plantilla que muestran los subtotales/totales procesan desde 0,1 segundos hasta 1 segundo para conjuntos muy grandes. Los llamo alrededor de 6 veces en el informe, por lo que no parecen el mayor problema.
Ahora, me encontré con un perfilador de Python y volvió 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 viene a la cabeza, que pueden hacer un cierto sentido como lo estoy haciendo una gran cantidad de formato de número . Decimal.py tiene sentido ya que el informe es esencialmente un 90% de números. No tengo idea de cuál es el método incorporado match
, ya que no estoy haciendo ningún Regex o similar en mi propio código (¿Algo está haciendo Django?) Lo más parecido es que estoy usando itertools ifilter.
Parece que esos son los principales culpables y si pudiera encontrar la manera de reducir el tiempo de procesamiento de aquellos, 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 solucionarí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 los resultados fueron prácticamente los mismos, el último fue un poco más rápido pero no fue la causa del problema. ¿Qué está pasando exactamente en tokenize.py?
Es imposible sugerir algo útil sin su código de vista y guía de generación de perfiles. –
Alex: Mi opinión es bastante simple. Retira una lista inicial de entradas, luego, si se modifica el informe, agrega algunos filtros. Eso es realmente todo. Mi plantilla luego reagrupa el conjunto de datos en dos secciones y luego recorre todo, llamando listones en el camino (Pero he programado las etiquetas de la plantilla para que se ejecuten en 0.1 -> 0.5 segundos ... estas plantillas list son los subtotales/totales del informe para que el tiempo de ejecución sea aceptable en grandes conjuntos de datos.) – Bartek
@Bartek: por favor, no comenten su propia pregunta. Es su pregunta, puede actualizarla para contener todos los hechos relevantes. –