惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

酷 壳 – CoolShell
酷 壳 – CoolShell
H
Hacker News: Front Page
P
Palo Alto Networks Blog
T
ThreatConnect
Apple Machine Learning Research
Apple Machine Learning Research
博客园_首页
T
True Tiger Recordings
P
Privacy & Cybersecurity Law Blog
B
Blog
IT之家
IT之家
Last Week in AI
Last Week in AI
F
Full Disclosure
Hacker News: Ask HN
Hacker News: Ask HN
C
Comments on: Blog
Microsoft Azure Blog
Microsoft Azure Blog
C
Cybersecurity and Infrastructure Security Agency CISA
Microsoft Security Blog
Microsoft Security Blog
博客园 - 【当耐特】
N
News and Events Feed by Topic
NISL@THU
NISL@THU
腾讯CDC
雷峰网
雷峰网
Security Latest
Security Latest
李成银的技术随笔
M
Microsoft Research Blog - Microsoft Research
L
LangChain Blog
L
Lohrmann on Cybersecurity
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
C
Check Point Blog
Y
Y Combinator Blog
Recent Announcements
Recent Announcements
博客园 - Franky
N
News | PayPal Newsroom
V
V2EX
A
About on SuperTechFans
The Register - Security
The Register - Security
月光博客
月光博客
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Google Online Security Blog
Google Online Security Blog
MyScale Blog
MyScale Blog
Cisco Talos Blog
Cisco Talos Blog
Vercel News
Vercel News
WordPress大学
WordPress大学
C
Cyber Attacks, Cyber Crime and Cyber Security
The Hacker News
The Hacker News
IntelliJ IDEA : IntelliJ IDEA – the Leading IDE for Professional Development in Java and Kotlin | The JetBrains Blog
IntelliJ IDEA : IntelliJ IDEA – the Leading IDE for Professional Development in Java and Kotlin | The JetBrains Blog
爱范儿
爱范儿
A
Arctic Wolf
L
LINUX DO - 最新话题
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More

博客园 - 赵青青

AI模型Claude的Haiku、Sonnet、Opus 怎么选? obsidian(md笔记管理)使用实践 python中可变参数与装饰器的例子 C++ lambda 表达式 3ds max的obj文件格式说明 CPython调试和性能分析 Python3类型安全type hint Python3虚拟机和对象 vs编译cpp时设置排除项 与ChatGPT的对话在windows上获取mac地址 最小体积拉取git仓库并保持可更新 unity .net8 suppot comming pycharm一些减少代码warning的拼写检查设置 JavaScript速查表 Python cheatsheet 速查表 DirectX9(D3D9)游戏开发:高光时刻录制和共享纹理的踩坑 FFmpeg在游戏视频录制中的应用:画质与文件大小的综合比较 c++中字符串之string和char IMGUI快速入门
Python311新特性-特化指令specializing adaptive interpreter-typing-asyncio
赵青青 · 2024-11-03 · via 博客园 - 赵青青

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) —— 特化后的指令(非常快)

img

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

碰到问题

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

示例函数代码如下:

>>> def f(x):
...     return x*x
... for i in range(100):
...     f(i)

image-20241028155628526

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

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

>>> 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中并执行一遍

image-20241028161816185

还有一种方法就是:稍稍调整一下代码,把dis加到.py中,然后运行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种不能完成特化?

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

image-20241103104311246

image-20241103104308223

如何让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.

简单的例子发挥不出作用

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的作用

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

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())