元组推导式时间分析

3

最近我一直在对我的脚本进行时间分析。关于元组推导式,我在Stack Overflow上找到了几个帖子指出有两种方法:

  • list comprehension + tuple()

    >>> tuple([i for i in xrange(1000000)])
    
  • tuple comprehension

    >>> tuple(i for i in xrange(1000000))
    
我��以下事实感到困惑:cProfiletimeit告诉我第一种方法比第二种方法更快,但命令行中的timekernprof线性分析器却说相反。
以下是具体情况:
>>> import cProfile
>>> cProfile.run('tuple([i for i in xrange(1000000)])')
1000003 function calls in 0.139 seconds
>>> cProfile.run('tuple(i for i in xrange(1000000))')
1000003 function calls in 0.478 seconds 

>>> import timeit
>>> timeit.timeit('tuple([i for i in xrange(1000000)])')
0.08100390434265137
>>> timeit.timeit('tuple(i for i in xrange(1000000))')
0.08400511741638184

使用test_tuple_list.py:

tuple([i for i in xrange(1000000)])

并测试test_tuple_generator.py文件:

tuple(i for i in xrange(1000000))

我得到:

$time python test_tuple_list.py
real 0m0.398s
user 0m0.171s
sys 0m0.202s

$time python test_tuple_generator.py
real 0m0.333s
user 0m0.109s
sys 0m0.234s

使用test_tuple_list_kernprof.py

@profile
def test():
    tuple([i for i in xrange(1000000)])
test()

还有 test_tuple_generator_kernprof.py:

@profile
def test():
   tuple(i for i in xrange(1000000))
test()

我理解的是:

$kernprof.py -lv test_tuple_list_kernprof.py
Total time: 0.861045 s

$kernprof.py -lv test_tuple_generator_kernprof.py
Total time: 0.444025 s

我假设这些分析器之间的差异源于它们进行分析的方式,但是为什么它们会互相矛盾呢?
谢谢。

1
没有元组推导。你需要使用tuple()函数调用和生成器表达式。 - Martijn Pieters
timeit 的结果非常接近,真的很难说。 - Martijn Pieters
1
只使用 timeit,结果非常接近,很难说哪个更快。它们的速度几乎相同。 - Martijn Pieters
你知道为什么cProfile会产生如此不同的结果吗? - Raphael_LK
1
Python解释器将对整个事件序列调用分析器函数。因此,在执行生成器表达式期间,将触发一系列分析事件,每个事件都会稍微减慢执行速度。相反,运行列表推导式时,也会触发不同的一组分析事件,同样会减慢执行速度。由于事件模式不同,总体减速也不同。你不再测量代码,而是比较分析器如何对每段代码做出反应。 - Martijn Pieters
显示剩余4条评论
1个回答

2
不要使用分析器来测量两个 Python 代码片段之间的总时序差异。分析器会严重影响解释器中的代码执行时间,因为不同的代码路径将在不同的时间触发 sys.set_trace() 跟踪函数,而跟踪函数本身可能会为完全扭曲结果的不同事件引入微妙的时间差异,使您的数据对于绝对时间比较毫无用处。
在进行分析时,您同时在衡量分析器如何对不同的代码路径做出反应以及您正在衡量的代码路径本身。这适用于当您想要确定复杂代码中所有执行时间的位置时,但纯粹根据它们执行速度比较两个不同的代码片段是非常糟糕的。
那就只剩下你的 timeit 结果了,它们太接近了,难以区分哪个更快。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接