Python 3.11:
$ python -m pyperf timeit -s 'd = [0] * 10000' -- 'sum(d)'.....................Mean +- std dev: 39.0 us +- 1.0 us
Python3.10 和 3.11 之间的区别在于,通过在 sum 函数的快速加法分支中内联对单个数字 PyLongs 的解包,可以提升在单个数字 PyLongs 上调用 sum 的性能 。这样做可以避免在解包时python/blob/125cdcf504a5d937b575cda3552b233dd44ba127/Python/bltinmodule.c#L2485-L2490" rel="external nofollow noreferrer">调用 python/cpython/blob/de6981680bcf6496e5996a853b2eaa700ed59b2c/Objects/longobject.c#L489" rel="external nofollow noreferrer">PyLong_AsLongAndOverflow 。
值得注意的是,python/cpython/issues/68264#issuecomment-1285351158" rel="external nofollow noreferrer">在某些情况下,Python 3.11 在整数求和时仍然明显慢于 Python 2.7 。我们希望在 Python 中通过python/ideas/discussions/147" rel="external nofollow noreferrer">实现更高效的整数,获得更多的改进 。
精简列表的扩容操作,提升了 list.append 性能在 Python 3.11 中,list.append 有了显著的性能提升(大约快 54%) 。
Python 3.10 的列表 append:
$ python -m pyperf timeit -s \'x = list(map(float, range(10_000)))' -- '[x.append(i) for i in range(10_000)]'.....................Mean +- std dev: 605 us +- 20 us
Python 3.11 的列表 append:
$ python -m pyperf timeit -s \'x = list(map(float, range(10_000)))' -- '[x.append(i) for i in range(10_000)]'.....................Mean +- std dev: 392 us +- 14 us
对于简单的列表推导式 , 也有一些小的改进:
Python 3.10:
$ python -m pyperf timeit -s \'' -- '[x for x in list(map(float, range(10_000)))]'.....................Mean +- std dev: 553 us +- 19 us
Python 3.11:
$ python -m pyperf timeit -s \'' -- '[x for x in list(map(float, range(10_000)))]'.....................Mean +- std dev: 516 us +- 16 us
译注:记得在 3.9 版本的时候,Python 优化了调用 list()、dict() 和 range() 等内置类型的速度,在不起眼处 , 竟还能持续优化!
减少了全 unicode 键的字典的内存占用这项优化令 Python 在使用全为 Unicode 键的字典时,缓存的效率更高 。这是因为使用的内存减少了 , 那些 Unicode 键的哈希会被丢弃,因为那些 Unicode 对象已经有哈希了 。
例如,在 64 位平台上,Python 3.10 运行结果:
>>> sys.getsizeof(dict(foo="bar", bar="foo"))232
在 Python 3.11 中:
>>> sys.getsizeof(dict(foo="bar", bar="foo"))184
(译注:插个题外话,Python 的 getsizeof 是一种“浅计算”,这篇《Python在计算内存时应该注意的问题?》区分了“深浅计算” , 可以让你对 Python 计算内存有更深的理解 。)
提升了使用asyncio.DatagramProtocol 传输大文件的速度asyncio.DatagramProtocol
提供了一个用于实现数据报(UDP)协议的基类 。有了这个优化,使用asyncio UDP 传输大文件(比如 60 MiB)将比 Python 3.10 快 100 多倍 。
这是通过计算一次缓冲区的大小并将其存储在一个属性中来实现的 。这使得通过 UDP 传输大文件时 , asyncio.DatagramProtocol
有着数量级的提速 。
PR msoxzw 的作者提供了以下的 测试脚本 。
对于 math 库:优化了 comb(n, k) 与 perm(n, k=None)Python 3.8 在math
标准库中增加了 comb(n, k) 和 perm(n, k=None) 函数 。两者都用于计算从 n 个无重复的元素中选择 k 个元素的方法数 , comb
返回无序计算的结果,而perm
返回有序计算的结果 。(译注:即一个求组合数,一个求排列数)
3.11 的优化由多个较小的改进组成,比如使用分治算法来实现 Karatsuba 大数乘法,以及尽可能用 C 语言unsigned long long
类型而不是 Python 整数进行comb
计算(python/cpython/pull/29090#issue-1031333783" rel="external nofollow noreferrer">*) 。
另外一项改进是针对较小的 k 值(0 <= k <= n <= 67):
(译注:以下两段费解,暂跳过)
对于0 <= k <= n <= 67
,comb(n, k)
always fits into auint64_t
. We compute it ascomb_odd_part << shift
where2 ** shift
is the largest power of two dividingcomb(n, k)
andcomb_odd_part
iscomb(n, k) >> shift
.comb_odd_part
can be calculated efficiently via arithmetic modulo2 ** 64
, using three lookups and twouint64_t
multiplications, while the necessary shift can be computed via Kummer's theorem: it's the number of carries when addingk
ton - k
in binary, which in turn is the number of set bits of推荐阅读
- 微信好友删除了怎么找回(微信注销60天后警察还能查到吗)
- 只知道微信昵称删除了对方怎么找对方(彻底删除对方微信)
- 微信删除好友怎么找回(微信已经实行双向删除了吗)
- 微信读书有声书怎么查看
- RAID5 IO处理之条带读代码详解
- Learning Records 计算机网络
- 重写 hashcode真有那么简单嘛?
- 遇到这样的女人一定要把握住,除了重感情心里还非常的善良豁达
- 万万没有想到老鹰不是食物链顶端,经常被猫头鹰捕食,你怎么看?
- 除了 三高检查大概要多少钱