Shell Python与WSGI Python的执行时间

Shell Python与WSGI Python的执行时间,python,django,performance,shell,time,Python,Django,Performance,Shell,Time,我花了很长时间分析了一些Django代码(试图找到性能问题的根本原因),这些代码将queryset转换为HTML标记列表 所讨论的queryset大约有8000条记录,但分析表明,数据库/SQL不是问题所在,因为实际查询大约在1毫秒内执行 经过数小时的努力,我无意中发现,通过Apache/WSGI运行特定代码似乎在性能问题中扮演了重要角色 为了将问题缩小到一行Python代码,我将其包装在一个“时钟”中以测量其性能,如下所示: import time start_time = time.clo

我花了很长时间分析了一些Django代码(试图找到性能问题的根本原因),这些代码将queryset转换为HTML标记列表

所讨论的queryset大约有8000条记录,但分析表明,数据库/SQL不是问题所在,因为实际查询大约在1毫秒内执行

经过数小时的努力,我无意中发现,通过Apache/WSGI运行特定代码似乎在性能问题中扮演了重要角色

为了将问题缩小到一行Python代码,我将其包装在一个“时钟”中以测量其性能,如下所示:

import time

start_time = time.clock()
records    = list(query_set)                  # <--- THIS LINE IS THE CULPRIT
total_time = time.clock() - start_time
with open('some_path/debug.txt', 'a') as f:
    f.write('%f\n'%total_time)
所讨论的代码存在于一个函数中,我可以方便地从Django管理shell调用该函数并手动运行,这允许我获取第二个计时指标

有人能告诉我到底是什么导致了这一行的执行时间翻倍。显然,该行调用了相当多的内置Django代码,但是代码的执行方式如何能产生如此巨大的差异呢

如何在Apache/WSGI中获得与在shell中相同的性能

请注意,我正在守护进程模式(不是嵌入式模式)下运行Django应用程序,而我的应用程序的其余部分没有出现性能问题。只是我从未想过shell和Apache/WSGI之间的差异会导致性能差异,对于这段特定的代码,更不用说任何差异了

更新1
我忘了提到,我尝试在nginx/uWSGI中运行相同的代码,但出现了相同的问题,所以似乎不是Apache出了问题。可能是WSGI本身的工作方式

更新2
所以情节变厚了…
list(query\u set)
行代码对我来说不是多线程的,但是如果我稍微改变我的实现并在多线程代码中对查询集进行实际迭代:

def threaded_func(query_set_slice): # Gets invoked by multiple threads created by me
    start_time = time.clock()
    for record in query_set_slice:
        ... do stuff ...
    total_time = time.clock() - start_time
    with open('some_path/debug.txt', 'a') as f:
        f.write('%f\n'%total_time)
。。。执行时间仍然存在差异(在shell和Apache/WSGI之间),但这一次的比率是相反的。
即数字如下:

Apache/WSGI: 0.824394 (seconds)
Shell:       1.890437 (seconds)
有趣的是,由于线程化函数的比率与前面的比率相反,因此对于两种类型的调用(Apache/WSGI和Shell),调用线程化函数的函数的执行时间是相同的

更新3
在对
time.clock()
做了一些研究之后,似乎不能一直相信它,所以我尝试了
time.time()
,结果得到了大约1:1的比率。

我还尝试了
LineProfiler
,它给出了1:1的比率,所以我猜
time.clock()
没有考虑上下文切换和类似的事情。

您能运行
timeit
循环,并对该调用进行至少几次迭代吗?还有,为什么要将查询集转换为列表,而不是对其进行迭代?我没有平均花费1000秒的时间(主要是因为这会花费太长),但我至少尝试了10次,每次都得到了大致相同的比率。您还想让我试试
timeit
?如果是,迭代次数(请记住,单个迭代的最坏情况需要约1.2秒)。我正在将其转换为一个列表,以便使用多线程/多处理来并行执行:queryset-->标记的实际任务。如果我没有将它并行化,那将是瓶颈。不,听起来你已经解决了它,我只是好奇。我知道很难拒绝质疑我为什么要做这个计算,但我真的想关注调用之间的区别。例如,我尝试通过两种方式执行非缓存的递归斐波那契函数,但没有得到2:1的比率,但得到的比率约为17:24。不要使用
time.clock()
;其行为依赖于平台。改用
timeit.default\u timer
(它根据操作系统、Python版本选择
time.clock
time.time
time.perf\u counter
中的最佳值)。
Apache/WSGI: 0.824394 (seconds)
Shell:       1.890437 (seconds)