Python 3.11 你应该试试的超酷特性:六、更快的启动速度

631 阅读3分钟

Python 3.11 你应该试试的超酷特性

Python 3.11在10月24日发布。它是Python最新版本,运行速度更快且更佳友好。在经过17个月的研发,终于到了可以使用的黄金时期。

和每个发布版本一样,Python 3.11做了大量的变更及提高。你可以通过查看文档来了解大部分内容。这里,我们会阐述最酷且最有影响力的新特性。

教程里将涵盖如下内容:

  • 更好的错误信息来帮助代码追踪
  • Faster CPython项目加速代码执行
  • 在异步代码中使用Task和exception groups
  • Python静态类型新增的几个类型特性
  • 原生支持TOML格式配置文件

如果你想运行本教程所提供的示例文件,你需要先安装Python 3.11.

更快的启动速度

Faster CPython另一个贡献是更快的启动时间。当我们执行Python时,解释器需要做一些初始化的工作。这就导致即便是很简单的应用程序也有花费一些毫秒时间来执行。

$ time python3.8 -c "pass"

real	0m0.024s
user	0m0.012s
sys	0m0.012s

我们可以直接传递-c参数来简单执行代码。这里我们整个程序就一个pass语句,啥也没干。

大部分来说该执行时间相对于代码整体时间来说可以忽略不计。但是对于一些小的脚本,例如命令行程序,启动时间可能相对来说比较影响用户体验。

我们来个具体的例子,灵感来自cowsay应用:

# snakesay.py
import sys


message = " ".join(sys.argv[1:])
bubble_length = len(message) + 2
print(
    rf"""
       {"_" * bubble_length}
      ( {message} )
       {"‾" * bubble_length}
        \
         \    __
          \  [oo]
             (__)\
               λ \\
                 _\\__
                (_____)_
               (________)Oo°"""
)

在snakesay.py,我们从命令行执行接收参数。然后将参数从小蛇的气泡图给打印出来:

$ python snakesay.py Beautiful is better than ugly.

       ________________________________
      ( Beautiful is better than ugly. )
       ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
        \
         \    __
          \  [oo]
             (__)\
               λ \\
                 _\\__
                (_____)_
               (________)Oo°

虽然它执行很快,也要耗费一些毫秒数。这里很大一部分时间是花在了Python模块导入中,就算我们没有指定导入包,内部同样隐私做了导入操作。

我们可以使用-X importtime选项来查看导入模块所花费的时间

$ python3.10 -X importtime -S snakesay.py Beautiful is better than ugly.
import time: self [us] | cumulative | imported package
import time:       183 |        183 |   _io
import time:        42 |         42 |   marshal
import time:       376 |        376 |   posix
import time:       637 |       1237 | _frozen_importlib_external
import time:        96 |         96 |   time
import time:       428 |        523 | zipimport
import time:       151 |        151 |     _codecs
import time:       485 |        635 |   codecs
import time:       440 |        440 |   encodings.aliases
import time:       620 |       1694 | encodings
import time:       251 |        251 | encodings.utf_8
import time:        94 |         94 | _signal
import time:        56 |         56 |     _abc
import time:       265 |        320 |   abc
import time:       285 |        605 | io

       ________________________________
      ( Beautiful is better than ugly. )
       ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
        \
         \    __
          \  [oo]
             (__)\
               λ \\
                 _\\__
                (_____)_
               (________)Oo°

这里表里的数值为微妙,最后的缩进格式用来指明模块引入关系,例如这里,io是顶级导入,然后abc由io导入。这里-S是减少过多的包列出,你可以不管它。

以下表是针对Python 3.10和3.11包导入的时间优化:

ModulePython 3.11Python 3.10提速
_frozen_importlib_external15732551.43x
zipimport3585581.56x
encodings261130091.15x
encodings.utf_84174090.98x
_signal1741730.99
io61612161.97x
Total574976201.33x

你机器上运行实际值可能不一样,但是总体来说Python3.11启动速度更快。

该速度的提升主要原因是引入了cached字节码。众所周知,Python通过解释器将源代码编译为字节码,将字节码存在__pycache__目录避免重复编译。

Python新版,将很多模块是固定直接加载到内存中,以便得到速度提升。你可以阅读文档来了解更多内容