pt1*_*lol 6 python yield list generator coroutine
Python 3.6.8 (default, Oct 7 2019, 12:59:55)
Type 'copyright', 'credits' or 'license' for more information
IPython 7.9.0 -- An enhanced Interactive Python. Type '?' for help.
In [1]: def yield_from_generator():
...: yield from (i for i in range(10000))
...:
In [2]: def yield_from_list():
...: yield from [i for i in range(10000)]
...:
In [3]: import timeit
In [4]: timeit.timeit(lambda: list(yield_from_generator()), number=10000)
Out[4]: 5.3820097140014695
In [5]: timeit.timeit(lambda: list(yield_from_list()), number=10000)
Out[5]: 4.333915593000711
Run Code Online (Sandbox Code Playgroud)
我多次运行yield from生成器并yield from列出。列表版本总是提供更好的性能,而我的直觉告诉我相反的结论 - 制作列表需要在启动时分配内存。为什么我们可以注意到这种性能差异?
简而言之,表面语法使它们看起来比实际情况更相似
\n\n我将更详细地分解一系列函数(该dis模块对此很有帮助),我将把它们分成设置成本和每个产生值的成本。我们从以下开始:
def yield_from_generator():\n yield from (i for i in range(10000))\nRun Code Online (Sandbox Code Playgroud)\n\n费用是:
\n\ngenexpr,它还会调用迭代器next上的a range。请注意,这里有两个上下文切换接下来我们看:
\n\ndef yield_from_list():\n yield from [i for i in range(10000)]\nRun Code Online (Sandbox Code Playgroud)\n\n成本是:
\n\nlist操作码,所以会很快list迭代器,所以速度很快接下来我们看一个类似的函数:
\n\ndef yield_from_list2():\n yield from list(i for i in range(10000))\nRun Code Online (Sandbox Code Playgroud)\n\n这不使用特殊的列表操作码,并且具有生成器的双重嵌套,因此又很慢。成本是:
\n\nlist迭代器,所以又快了最后是一个快速版本,只是强调yield from:
def yield_from_generator2():\n yield from range(10000)\nRun Code Online (Sandbox Code Playgroud)\n\n成本是:
\n\nrange对象range直接恢复迭代器我的笔记本电脑上所有这些的时间是:
\n\nyield_from_generator 639 \xc2\xb5s\nyield_from_list 536 \xc2\xb5s\nyield_from_list2 689 \xc2\xb5s\nyield_from_generator2 354 \xc2\xb5s\nRun Code Online (Sandbox Code Playgroud)\n\n希望现在更清楚了。另一个版本是:
\n\ndef yield_from_list3():\n yield from list(range(10000))\nRun Code Online (Sandbox Code Playgroud)\n\n运行在 401 \xc2\xb5s 但希望更明显为什么它位于中间,性能方面
\n| 归档时间: |
|
| 查看次数: |
637 次 |
| 最近记录: |