Python311新特性-特化指令specializing adaptive interpreter-typing-asyncio

Python3新特性

python3.11增加了许多特性,让python更快更加安全,本文从应用层面来讲一下python3.11的这些新特性

特化自适应解析器是什么,如何利用特化写出更高性能的代码

如何在项目中落地type hint写出健壮的代码,有那些注意事项

asyncio的概念及应用场景

Faster Python 3.11

Faster

  1. Zero cost exception(if not thrown)
  2. 10% faster re & atomic grouping, possessive qualifiers
  3. 10-15% faster startup
  4. Faster function calls
  5. C-style formatting sometimes as fast as f-string
  6. Less memory for string keys in dicts
  7. Specialized adaptive interpreter
  8. And more!

Future

  1. Major focus for the next several releases
  2. Simple JIT planned eventually
  3. The main driver behind C API changes

Specializing(特化)

当一个函数被执行的次数足够多(>53)就会被特化,被特化的指令叫hot code。(次数需要看对应不同版本cpython源码)

源码:Python/specialize.c -> _PyCode_Warmup

特化流程:

​ 原始指令 ------ 中间状态(名称中含ADAPTIVE) ------ 特化后的指令(非常快)

图片来源:Python3-源码剖析(二)-指令特化 | Yuerer's Blog

碰到问题

同样的代码在命令行中可以被特化,而放一个.py文件中,再通过dis.dis(module.func,adaptive=True)就无法被特化

示例函数代码如下:

shell 复制代码
>>> def f(x):
...     return x*x
... for i in range(100):
...     f(i)

解释:乘法的opcode为BINARY_OP,在这个例子中我们传的是int当被特化后会变成BINARY_OP_MULTIPLY_INT,因为python弱类型,确定的类型可以极大提高速度,建议去看cpython的实现源码加深理解。

把上面代码放在.py文件中,发现无法进行特化

shell 复制代码
>>> dis.dis(adaptiveTest.f,adaptive=True)
 10           RESUME                   0

 11           LOAD_FAST                0 (x)
              LOAD_CONST               1 (2)
              BINARY_OP                5 (*)
              RETURN_VALUE

最终找到原因:我在vscode自带的终端import之后,在运行时修改了py代码,没有重新reload,导致没有加载最新的代码(py3的reload和py2有区别)。

另一个方法就是:重新打开windows的cmd中并执行一遍

还有一种方法就是:稍稍调整一下代码,把dis加到.py中,然后运行python文件也可以看到函数被特化

python 复制代码
import dis
def foo(x):
	return x*x

for i in range(100):
	foo(i)

dis.dis(foo,adaptive=True)
#在python中调用dis打印出字节码

LOAD_ATTR(getattr)特化

self.xx 本质就是getattr,对应的opcode为 LOAD_ATTR,在python3中默认可以被特化,例如:

  1. 继承object的原生Python类可以特化

  2. 继承后object重写 __getattr__ 的Python 类无法特化

  3. C 扩展 Python 类无法特化

为什么后面2种不能完成特化?

python 复制代码
class B(object):
	def __getattr__(self, name):#重写__getattr__
		return super(B, self).__getattr__(name)

b = B()
b.x = 1
def mytest(n):
	for i in range(n):
		b.x #无法被特化

因为:cpython中特化前判断是否为原始的getattr函数,见:Python\specialize.c

如何让C扩展python类可以特化?

重点讲解:2种实现方法

  1. 在c扩展类中增加cache保存下标
  2. 修改虚拟机的实现,传入下标

如何检查代码是否被特化?

可视化特化工具,github:https://github.com/brandtbucher/specialist

运行代码并生成(网页)报表,那么如何纳入到项目中进行可视化呢?因为游戏项目依赖于引擎API,需要跑在游戏引擎之上,不同于纯python环境

Typing check(type hint)

base vscode Pylance

Type Ignore

pyrightconfig.json 兼容py2的文件,忽略整个文件

overload

配合vscode的pylance特性来做代码检查

当函数传参个数不符合要求时,在IDE中进行报错提示

Stub Files

和py同名的文件格式为.pyi,语法也一样,在这里写type hint,提供给IDE使用,运行时无关

AsyncIO

What is it?

Keywords pair(async / await)

So what?

What is it?

Asyncio is used as a foundation for multiple Python asynchronous frameworks that

provide high-performance network and web-servers, database connection libraries,

distributed task queues, etc.

Asyncio is often a perfect fit for IO-bound and high-level structured network code.

简单的例子发挥不出作用

python 复制代码
import asyncio
async def foo():
	await asyncio.sleep(1)
	print ('foo')
event_loop = asyncio.get_event_loop()
event_loop.run_until_complete(foo())

上面这个简单的asyncio的例子和下面这段代码作用一样,无法体现出asyncio的作用

python 复制代码
def foo():
	time.sleep(1)
	print('foo')
foo()

适合用在那些地方?

Patch

  • Simultaneously download multiple block of patch

Distributed Task Framework

  • Multi-Process Management through ProcessPoolExecutor
  • Export-table-tools
  • Texture Compressor
  • build packer

感兴趣的可以搜索ProcessPoolExecutor去了解

UVLoop

uvloop用来替换asyncio的event loop更高效,底层使用libuv通过cython实现,比原生的asyncio快2~4倍,有线上项目已验证过其稳定性

开源地址:https://github.com/MagicStack/uvloop

简单几行就可以替换asyncio的event loop

python 复制代码
import asyncio
import sys

import uvloop

async def main():
    # Main entry-point.
    ...

if sys.version_info >= (3, 11):
    with asyncio.Runner(loop_factory=uvloop.new_event_loop) as runner:
        runner.run(main())
else:
    uvloop.install()
    asyncio.run(main())
相关推荐
古希腊掌管学习的神20 分钟前
[搜广推]王树森推荐系统——矩阵补充&最近邻查找
python·算法·机器学习·矩阵
LucianaiB1 小时前
探索CSDN博客数据:使用Python爬虫技术
开发语言·爬虫·python
PieroPc3 小时前
Python 写的 智慧记 进销存 辅助 程序 导入导出 excel 可打印
开发语言·python·excel
梧桐树04297 小时前
python常用内建模块:collections
python
Dream_Snowar7 小时前
速通Python 第三节
开发语言·python
蓝天星空9 小时前
Python调用open ai接口
人工智能·python
jasmine s9 小时前
Pandas
开发语言·python
郭wes代码9 小时前
Cmd命令大全(万字详细版)
python·算法·小程序
leaf_leaves_leaf9 小时前
win11用一条命令给anaconda环境安装GPU版本pytorch,并检查是否为GPU版本
人工智能·pytorch·python
夜雨飘零19 小时前
基于Pytorch实现的说话人日志(说话人分离)
人工智能·pytorch·python·声纹识别·说话人分离·说话人日志