Django(?)在进行一些python性能分析后,对于大型数据集确实很慢

Bar*_*tek 5 python django optimization

我正在比较我的旧PHP脚本与较新的,更高级的Django版本和PHP版本,完全吐出HTML并且所有功能都运行得更快.更快到Django上的某些东西必须出错.

首先,一些背景信息:我有一个页面可以显示销售数据的报告.数据可以通过许多方式进行过滤,但大部分都是按日期过滤的.这使得缓存它有点困难,因为结果的可能性几乎是无穷无尽的.有很多数字和计算完成但在PHP中处理从来都不是一个问题.

更新:

  • 经过一些额外的测试后,我的观点中没有任何因素导致经济放缓.如果我只是对数据进行数字处理并吐出5行渲染的HTML,那就不那么慢(仍然比PHP慢),但如果我渲染了大量数据,那就非常慢了.

  • 每当我运行大型报告(例如,当年的所有销售)时,机器的CPU使用率就会达到100%.不知道这是否意味着什么.我正在使用mod_python和Apache.也许转换到WSGI可能会有所帮助?

  • 对于非常大的集合,我的模板标签显示小计/总计处理的范围从0.1秒到1秒.我在报告中称他们为6次,所以他们似乎不是最大的问题.

现在,我运行了一个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是什么,因为我没有在我自己的代码中做任何正则表达式或类似的东西(Django正在做什么?)最接近的是我使用的是itertools ifilter.

这似乎是主要的罪魁祸首,如果我能弄清楚如何减少那些处理时间,那么我会有一个更快的页面.

有没有人对如何开始减少这个有任何建议?我真的不知道如何解决这个令牌化/小数问题,而不是简单地删除它们.

更新:我在大多数数据上使用/不使用过滤器进行了一些测试,结果时间几乎相同,后者速度稍快但不是问题的原因.tokenize.py到底发生了什么?

Bry*_*ein 6

由于您没有任何类型的代码示例,因此有很多事情可以假设您的问题.

以下是我的假设:您正在使用Django的内置ORM工具和模型(即sales-data = modelobj.objects().all()),而在PHP方面,您正在处理直接SQL查询和使用query_set.

Django正在进行大量的类型转换和转换,数据类型从数据库查询到ORM/Model对象和关联的管理器(默认情况下为objects()).

在PHP中,您控制转换并确切地知道如何从一种数据类型转换为另一种数据类型,您只需基于该问题节省一些执行时间.

我建议尝试将一些奇特的数字工作转移到数据库中,特别是如果你正在进行基于记录集的处理 - 数据库吃早餐时的那种处理.在Django中,您可以将RAW SQL发送到数据库:http://docs.djangoproject.com/en/dev/topics/db/sql/#topics-db-sql

我希望这至少可以让你指出正确的方向......