更多课程 选择中心


Python培训

400-996-5531

什么是Python整数缓存机制,一文说清楚!


整数,在Python中,不是以传统的2、4或8字节实现,而是将其实现为以230为基数的整数数组,因此Python支持超长整数。又因为整数没有明确的长度限制,所以在Python中使用整数非常方便,即使我们对很长的整数进行运算,也不必担心整数溢出。但这种便利的代价是资源分配较高,同时常用运算(例如加法,乘法,除法)的执行效率较低。

Python中的每个整数都实现为一个C语言结构体, 如下所示

可以观察到,与其它的较长整数相比,-5至256范围内的较小整数使用非常频繁,为了性能上优势,Python在初始化过程中预先分配了该范围内的整数对象,并使它们成为单例,因此每次在使用较小整数时, 使用的是相应单例的引用,而不是重新分配新的整数对象。

下面是Python官方文档中关于整数预分配的相关内容:

“当前的整数实现会为-5至256之间的所有整数维护一个整数对象数组,当你创建该范围内的整数时, 你实际得到的是现有整数对象的引用。”

在CPython的源码中,可以在IS_SMALL_INT宏和longobject.c模块中的get_small_int函数中跟踪此优化。因此,Python为常用整数节省了大量的空间和计算量。

验证这些较小整数对象是否是单例

对于CPython, 内置的id函数返回对象的内存地址。这意味着,如果较小整数确实是单例,对于相同较小整数值的两个实例, id函数应该返回相同的内存地址,而对于较长整数的多个实例应返回不同的内存地址,这确实是我们观察到的:

较小整数的这种单例现象也可以在计算过程中观察到。在下面的示例中,通过对三个不同的整数2、4和10进行两次运算,我们得到了相同的目标值6,并且在这两种情况下,我们看到id函数返回了相同的内存地址:

验证这些较小整数对象是否经常被引用

我们已经确定,在Python中使用较小整数,是通过引用它们相应的单例对象来实现,而无需每次都重新分配内存创建整数对象。现在我们需要验证以下假设:“Python初始化的时候, 通过这些单例对象,确实节省了大量的内存分配操作”;我们可以通过检查每个整数值的引用计数来验证上面的假设。

引用计数

引用计数,维护着同一对象在不同位置被引用的数目,对象每次被引用时,其属性ob_refcnt(对象引用计数)会增加1,对象引用被取消时, ob_refcnt会减少1,当引用计数为0时,该对象将会被垃圾回收。

我们使用sys模块中的getrefcount函数来获取一个对象的当前引用计数;较小整数的引用计数很高,表明使用率很高,同时引用计数随着这些整数值的增加而降低;这证实了, 在Python初始化期间, 相比于较长整数,较小整数被更多对象引用。

整数值0被引用的最多——359次,沿着分布图的长尾,可以看到引用计数的峰值为2的幂次,如32, 64, 128和256。Python在初始化的过程中本身需要较小整数值,因此通过单例模式节省了大约1993次的较小整数对象的创建。

这些引用计数是在新打开的Python进程计算的,这意味着,Python初始化时,需要使用一些整数值进行计算,并通过使用较小整数值的单例来加速计算。

在通常的编程实践中, 相比于较长整数,较小整数的使用更频繁,并且这些整数值的单例实例可以为Python节省大量的计算量和内存分配操作。

达内每年输送10万+人才,18年来帮助80万学员高薪就业;协助16万家企业解决人才需求。拥有完善的就业保障体系,116万家招聘雇主合作企业。每天产生数千个招聘岗位,提供更多就业机会给到达内学员。找Python培训,选达内就对了!

版权声明:转载文章来自公开网络,版权归作者本人所有,推送文章除非无法确认,我们都会注明作者和来源。如果出处有误或侵犯到原作者权益,请与我们联系删除或授权事宜。

预约申请免费试听课

填写下面表单即可预约申请免费试听! 怕学不会?助教全程陪读,随时解惑!担心就业?一地学习,可全国推荐就业!

上一篇:Python程序员最常犯的10个错误,你中招了吗?
下一篇:学习Python对于女生来说怎么样?

为什么要学习Python编程?

为什么有人学完Python找不到工作?

Python 到底牛在哪?

编程入门语言,为什么建议学Python?

Copyright © 2023 Tedu.cn All Rights Reserved 京ICP备08000853号-56 京公网安备 11010802029508号 达内时代科技集团有限公司 版权所有

选择城市和中心
黑龙江省

吉林省

河北省

湖南省

贵州省

云南省

广西省

海南省