Django(?)在完成一些python评测之后,处理大型数据集的速度非常慢

Django(?)在完成一些python评测之后,处理大型数据集的速度非常慢,python,django,optimization,Python,Django,Optimization,我比较了我的一个老PHP脚本和更新的、更花哨的Django版本和PHP版本,它们完全脱离了HTML,并且运行得更快。快得多,Django one肯定出了问题 首先,一些上下文:我有一个页面,可以显示销售数据的报告。数据可以通过多种方式过滤,但大部分是通过日期过滤的。这使得缓存它有点困难,因为结果的可能性几乎是无限的。有很多数字和计算已经完成,但在PHP中处理起来从来都不是什么大问题 更新: 经过一些额外的测试,在我看来没有什么是导致经济放缓的原因。如果我只是简单地对数据进行数字运算并输出5行呈

我比较了我的一个老PHP脚本和更新的、更花哨的Django版本和PHP版本,它们完全脱离了HTML,并且运行得更快。快得多,Django one肯定出了问题

首先,一些上下文:我有一个页面,可以显示销售数据的报告。数据可以通过多种方式过滤,但大部分是通过日期过滤的。这使得缓存它有点困难,因为结果的可能性几乎是无限的。有很多数字和计算已经完成,但在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) 订购人:内部时间 由于限制,名单从3074减至20 ncalls tottime percall cumtime percall文件名:lineno(函数) 2939417 26.290 0.000 44.857 0.000/usr/lib/python2.5/tokenize.py:212(生成_令牌) 2822655 17.049 0.000 17.049 0.000{内置方法匹配} 168992815.418 0.000 23.297 0.000/usr/lib/python2.5/decimal.py:515(新的) 12289605 11.464 0.000 11.464 0.000{isinstance} 8826189.6140.000 25.5180.000/usr/lib/python2.5/decimal.py:1447(_fix) 173938.7420.00160.7980.003/usr/lib/python2.5/tokenize.py:158(tokenize_循环) 11 7.886 0.717 7.886 0.717{u socket.socket'objects}的方法'accept' 365577 7.854 0.000 30.233 0.000/usr/lib/python2.5/decimal.py:954(添加) 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 60799 5.666 0.000 9.377 0.000/usr/lib/python2.5/site packages/django/db/models/base.py:241 17393 4.734 0.000 4.734 0.000{method'query'of'\u mysql.connection'objects} 1124348 4.631 0.000 8.469 0.000/usr/lib/python2.5/site packages/django/utils/encoding.py:44(强制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) 29732813.4240.000 3.4240.000/usr/lib/python2.5/decimal.py:718(非零) 759014 2.962 0.000 3.371 0.000/usr/lib/python2.5/decimal.py:4675(初始) 381756 2.806 0.000 128.447 0.000/usr/lib/python2.5/site packages/django/db/models/fields/related.py:231 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中到底发生了什么?

由于您没有任何类型的代码示例,因此有很多关于您的问题的假设

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

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

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

我建议您尝试将一些奇特的数字工作转移到数据库中,特别是如果您正在进行基于记录集的处理——数据库从早餐开始就开始进行这种处理。在Django中,您可以将原始SQL发送到数据库:

我希望这至少能为您指明正确的方向…

“tokenize.py位于顶部,由于我正在进行大量的数字格式化,这可能有一定的意义。”

毫无意义

tokenize模块提供了一个词汇表 Python源代码扫描程序, 用Python实现

Tokenize位于顶部意味着您正在进行动态代码解析

AFAIK(在Django存储库上进行搜索)Django不使用tokenize。因此,您的程序将执行某种动态代码实例化。或者,您只是对程序的第一次时间进行分析
Blog.objects.order_by('id').values()