python最新版311正式发布有哪些新特色?25

python是一种执行速度较慢的编程语言,这好像已经是业内对python的共同观点。例如,python语言中的循环比类似的C语言写成的循环,执行速度慢不止一个数量级。但一般来说,编程语言的开发效率比代码的执行速度更重要,python能使用很多扩展工具包,而这些工具包都是用执行速度比较快的语言开发的,如科学计算工具包Numpy就比python本身内置的计算方法快很多,也因为学习python编写代码更容易,使得python在数据科学领域有长足的应用。但python官方并没有忽略python代码执行速度慢的缺点,于2020年提出了改进性能的 Shannon 计划,按这份计划的要求,python代码未来的执行速度要比当年发布的版本提高5倍以上,并且确定在更快地 CPython的基础上进行改进。

python最新版311正式发布有哪些新特色?25

在官方声明文件 PEP 659中,描述了一个个性化的自适应解释器,其主要思想就是在提高代码执行速度的同时,对代码中经常出现的一些操作进行优化,且转换后的python二进制代码可以即时做出适应或改变,这和JIT(Just-in-time)编译的理念类似。众所周知,python代码在运行之前要被解释器编译为二进制代码,而二进制代码是由更多的基本指令组成,这些指令要比规范的python代码更多,因此每一行python代码都会转换为几个二进制代码语句。针对这个问题,看看下面的示例:

>>> def feet_to_meters(feet):
...     return 0.3048 * feet
...

上面这个函数,可以使用 dis 对该函数做反汇编处理,

>>> import dis
>>> dis.dis(feet_to_meters)
  1           0 RESUME                       0

  2           2 LOAD_CONST               1 (0.3048)
              4 LOAD_FAST                    0 (feet)
              6 BINARY_OP                    5 (*)
             10 RETURN_VALUE

上面是运行 dis.dis 函数后的结果, 可以看出每一行都是一个二进制代码指令,指令信息由五列,包括行号、字节地址、操作代码名称、操作参数和圆括号中的参数解释。对于编写python代码来说,不需要了解这样的细节,这里拿出来只是为了说明python运行的内在机制。提高python代码的执行速度所在的环节就在python代码转换并生成二进制代码这一步,获得了代码运行过程中可以被优化的指令,就可以用自适应指令来替代。当一个函数被调用的次数确定了,加速机制即刻实施。

可以进一步探究一下解释器如何通过调用 dis() 函数和 设置 adaptive 参数,来实现与二进制代码的自适应。看看下面的例子,定义一个函数,调用几次,其参数是一个浮点数:

>>> def feet_to_meters(feet):
...     return 0.3048 * feet
...

>>> feet_to_meters(1.1)
0.33528
>>> feet_to_meters(2.2)
0.67056
>>> feet_to_meters(3.3)
1.00584
>>> feet_to_meters(4.4)
1.34112
>>> feet_to_meters(5.5)
1.6764000000000001
>>> feet_to_meters(6.6)
2.01168
>>> feet_to_meters(7.7)
2.34696

接下来,看看 函数 feet_to_meters()运行7次后,该函数的二进制代码指令信息是什么样,

>>> import dis
>>> dis.dis(feet_to_meters, adaptive=True)
  1           0 RESUME                       0

  2           2 LOAD_CONST               1 (0.3048)
               4 LOAD_FAST                   0 (feet)
               6 BINARY_OP                   5 (*)
             10 RETURN_VALUE

从上面的运行结果中,看出有什么特别之处,函数feet_to_meters带参数和前面示例中不带参数的情况下,二进制代码的指令信息相同。接下来再运行一次,这是第8次运行该函数,看看该函数的二进制代码的指令信息发生了什么变化:

>>> feet_to_meters(8.8)
2.68224

>>> dis.dis(feet_to_meters, adaptive=True)
  1           0 RESUME_QUICK                          0

  2           2 LOAD_CONST__LOAD_FAST        1 (0.3048)
              4 LOAD_FAST                                   0 (feet)
              6 BINARY_OP_MULTIPLY_FLOAT      5 (*)
             10 RETURN_VALUE

可以看出,函数feet_to_meters() 被运行8次之后,原来的二进制指令已经被个性化的指令替代,如 BINARY_OP 被 BINARY_OP_MULTIPLY_FLOAT 替代,这能更快地计算两个浮点数相乘。即使参数 feet 是浮点数的情况下,feet_to_meters()函数被实施了优化,但是该函数在调用其他类型的参数时依然执行替换后的二进制指令;尽管内在操作发生了改变,但python代码的执行和python 3.11之前的版本完全一样。

再看看下面的例子,连续调用该函数多次,参数feet 用整数:

>>> for feet in range(52):
...            feet_to_meters(feet)
...

>>> dis.dis(feet_to_meters, adaptive=True)
  1           0 RESUME_QUICK                          0

  2           2 LOAD_CONST__LOAD_FAST        1 (0.3048)
               4 LOAD_FAST                                  0 (feet)
               6 BINARY_OP_MULTIPLY_FLOAT     5 (*)
             10 RETURN_VALUE

python解释器还是意在完成两个浮点数相乘这一操作,源代码转换为二进制代码指令集都是相同的。以上示例通过不同的参数类型表明,python 3.11在改变已有代码时无需考虑代码的执行速度。

python 3.11是在更快的CPython项目的基础上改进代码执行速度,但CPython有两个重要的原则:

  • 该项目的任何重大改变都不会引入到python,即python可以基于CPython改善执行速度,但不是说CPython的所有重大改进都会被引入到python
  • CPython的绝大部分代码都将会改进

这一点上有一个标准:CPython 3.11 比 CPython 3.0 平均快25%。因此,使用python 3.11应该更关注如何改进代码本身,而不是CPython 3.11 和 python 3.11 的标准之别。

CPython项目一直都在持续改进,其中有几个方面的优化将在2023年10月发布的Python 3.12中引入,该项目非常庞大,将涉及到python的所有方面。个性化的自适应解释器只是改进的内容之一。

发布者:股市刺客,转载请注明出处:https://www.95sca.cn/archives/76267
站内所有文章皆来自网络转载或读者投稿,请勿用于商业用途。如有侵权、不妥之处,请联系站长并出示版权证明以便删除。敬请谅解!

(0)
股市刺客的头像股市刺客
上一篇 2024 年 7 月 11 日
下一篇 2024 年 7 月 11 日

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注