Ami*_*ahi 47 python cpython list-comprehension python-internals dis
这是python-3.10中列表理解的反汇编:
Python 3.10.12 (main, Jun 11 2023, 05:26:28) [GCC 11.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import dis
>>>
>>> dis.dis("[True for _ in ()]")
1 0 LOAD_CONST 0 (<code object <listcomp> at 0x7fea68e0dc60, file "<dis>", line 1>)
2 LOAD_CONST 1 ('<listcomp>')
4 MAKE_FUNCTION 0
6 LOAD_CONST 2 (())
8 GET_ITER
10 CALL_FUNCTION 1
12 RETURN_VALUE
Disassembly of <code object <listcomp> at 0x7fea68e0dc60, file "<dis>", line 1>:
1 0 BUILD_LIST 0
2 LOAD_FAST 0 (.0)
>> 4 FOR_ITER 4 (to 14)
6 STORE_FAST 1 (_)
8 LOAD_CONST 0 (True)
10 LIST_APPEND 2
12 JUMP_ABSOLUTE 2 (to 4)
>> 14 RETURN_VALUE
Run Code Online (Sandbox Code Playgroud)
据我了解,它创建了一个名为的代码对象listcomp,该对象执行实际迭代并返回结果列表,并立即调用它。我无法弄清楚是否需要创建一个单独的函数来执行这项工作。这是一种优化技巧吗?
Abd*_*P M 66
创建函数的主要逻辑是隔离 compressive\xe2\x80\x99s 迭代变量peps.python.org。
\n通过创建一个函数:
\n\n\n理解迭代变量保持隔离,不会\xe2\x80\x99覆盖\n外部作用域中的同名变量,并且在理解后\n它们也不可见
\n
然而,这在运行时效率很低。由于这个原因,python-3.12实现了一种称为理解内联(PEP 709)peps.python.org的优化,它将不再创建单独的代码对象peps.python.org。
\n\n\n字典、列表和集合推导式现在是内联的,而不是为推导式的每次执行创建一个新的一次性函数对象。这可以将理解的执行速度提高多达\n两倍。有关更多详细信息,请参阅PEP 709 。
\n
以下是使用python-3.12反汇编的相同代码的输出:
\n>>> import dis\n>>> \n>>> dis.dis("[True for _ in ()]")\n 0 0 RESUME 0\n\n 1 2 LOAD_CONST 0 (())\n 4 GET_ITER\n 6 LOAD_FAST_AND_CLEAR 0 (_)\n 8 SWAP 2\n 10 BUILD_LIST 0\n 12 SWAP 2\n >> 14 FOR_ITER 4 (to 26)\n 18 STORE_FAST 0 (_)\n 20 LOAD_CONST 1 (True)\n 22 LIST_APPEND 2\n 24 JUMP_BACKWARD 6 (to 14)\n >> 26 END_FOR\n 28 SWAP 2\n 30 STORE_FAST 0 (_)\n 32 RETURN_VALUE\n >> 34 SWAP 2\n 36 POP_TOP\n 38 SWAP 2\n 40 STORE_FAST 0 (_)\n 42 RERAISE 0\nExceptionTable:\n 10 to 26 -> 34 [2]Run Code Online (Sandbox Code Playgroud)\n正如您所看到的,不再有MAKE_FUNCTION操作码,也不再有单独的代码对象。相反,python-3.12使用docs.python.org(在 offset 处)和(在 offset 处)操作码来为迭代变量提供隔离。LOAD_FAST_AND_CLEAR6STORE_FAST30
引用PEP 709 的规范部分peps.python.org :
\n\n\n迭代变量的隔离是通过offset 处的
\nx新操作码的组合来实现的,它在运行推导之前保存堆栈上的任何\n外部值,以及在运行后恢复 的外部值(如果有)\n n的理解。LOAD_FAST_AND_CLEAR6x30STORE_FASTx
除此之外,在python-3.12中 ,不再有一个单独的框架用于回溯中的理解。
\n| < python-3.12中的回溯 | python-3.12中的回溯 |
|---|---|
Run Code Online (Sandbox Code Playgroud) | Run Code Online (Sandbox Code Playgroud) |
这是peps.python.org 的基准测试结果(使用 MacOS M2 测量):
\n$ python3.10 -m pyperf timeit -s \'l = [1]\' \'[x for x in l]\'\nMean +- std dev: 108 ns +- 3 ns\n$ python3.12 -m pyperf timeit -s \'l = [1]\' \'[x for x in l]\'\nMean +- std dev: 60.9 ns +- 0.3 ns\nRun Code Online (Sandbox Code Playgroud)\n
| 归档时间: |
|
| 查看次数: |
3256 次 |
| 最近记录: |