T.N*_*Nel 51 python cpython python-2.7 python-internals
Python中的所有东西都是一个对象.因此Python中int的大小将比平常大.
>>> sys.getsizeof(int())
24
Run Code Online (Sandbox Code Playgroud)
好的,但为什么还需要12个字节才能进行2?³
比较2?³ - 1
,而不仅仅是一个?
>>> sys.getsizeof(2**63)
36
>>> sys.getsizeof(2**62)
24
Run Code Online (Sandbox Code Playgroud)
我得到的2?³
是一个long和2?³-1
一个int,但为什么12个字节的区别?
不再直观,我尝试了一些其他的东西:
>>> a = 2**63
>>> a -= 2**62
>>> sys.getsizeof(a)
36
Run Code Online (Sandbox Code Playgroud)
a
即使它现在可以在int中,仍然存储为long.所以这并不奇怪.但:
>>> a -= (2**63 - 1)
>>> a = 2**63
>>> a -= (2**63 - 1)
>>> a
1L
>>> sys.getsizeof(a)
28
Run Code Online (Sandbox Code Playgroud)
一个新的尺寸.
>>> a = 2**63
>>> a -= 2**63
>>> a
0L
>>> sys.getsizeof(a)
24
Run Code Online (Sandbox Code Playgroud)
回到24个字节,但仍然很长.
我得到的最后一件事:
>>> sys.getsizeof(long())
24
Run Code Online (Sandbox Code Playgroud)
题:
内存存储在这些场景中如何工作?
子问题:
为什么有12个字节的间隙来添加我们的直觉告诉我们只有1位?
为什么int()
和long()
24字节,但long(1)
已经是28字节和int(2?²)
?
注意:Python 3.X的工作方式略有不同,但并不直观.在这里,我专注于Python 2.7; 我没有测试以前的版本.
use*_*342 62
为什么它为2⁶³增加12个字节,相比之下2⁶³-1而不仅仅是1?
在LP64系统1上,Python 2 int
由三个指针大小的部分组成:
long int
这总共是24个字节.另一方面,Python long
包括:
2**63需要64位存储,因此它适合三个30位数字.由于每个数字的宽度为4个字节,因此整个Python long
将需要24 + 3*4 = 36个字节.
换句话说,差异来自于long
必须单独存储数字的大小(8个附加字节),并且与存储值相比空间效率稍差(12个字节用于存储2**63的数字).包括大小,值2**63在一个long
占用20个字节.将其与简单的任何值占用的8个字节进行比较,int
得出观察到的12字节差异.
值得注意的是,Python 3只有一个整数类型,称为int
可变宽度,并以与Python 2相同的方式实现long
.
long int
,据推测为具有大体的所用旧的代码源的兼容性char
,short
和long
对于如图8所示,也发生在工作16,和32位值作为"方便"的别名在16位和32位系统上.要在x86-64 Windows上获得实际的64位类型,必须使用__int64
或(在较新的编译器版本上)long long
或int64_t
.由于Python 2内部依赖于Python int
在不同的地方适应C长,所以sys.maxint
仍然存在2**31-1
,即使在64位Windows上也是如此.这个怪癖也在Python 3中修复,它没有maxint的概念.
虽然我没有在文档中找到它,但这是我的解释.
当值超过可以存储在int中的值时,Python 2 int
会long
隐式提升.新类型(long
)的大小是默认大小long
,即32.从现在开始,变量的大小将由其值上下决定.
from sys import getsizeof as size
a = 1
n = 32
# going up
for i in range(10):
if not i:
print 'a = %100s%13s%4s' % (str(a), type(a), size(a))
else:
print 'a = %100s%14s%3s' % (str(a), type(a), size(a))
a <<= n
# going down
for i in range(11):
print 'a = %100s%14s%3s' % (str(a), type(a), size(a))
a >>= n
a = 1 <type 'int'> 24
a = 4294967296 <type 'long'> 32
a = 18446744073709551616 <type 'long'> 36
a = 79228162514264337593543950336 <type 'long'> 40
a = 340282366920938463463374607431768211456 <type 'long'> 44
a = 1461501637330902918203684832716283019655932542976 <type 'long'> 48
a = 6277101735386680763835789423207666416102355444464034512896 <type 'long'> 52
a = 26959946667150639794667015087019630673637144422540572481103610249216 <type 'long'> 56
a = 115792089237316195423570985008687907853269984665640564039457584007913129639936 <type 'long'> 60
a = 497323236409786642155382248146820840100456150797347717440463976893159497012533375533056 <type 'long'> 64
a = 2135987035920910082395021706169552114602704522356652769947041607822219725780640550022962086936576 <type 'long'> 68
a = 497323236409786642155382248146820840100456150797347717440463976893159497012533375533056 <type 'long'> 64
a = 115792089237316195423570985008687907853269984665640564039457584007913129639936 <type 'long'> 60
a = 26959946667150639794667015087019630673637144422540572481103610249216 <type 'long'> 56
a = 6277101735386680763835789423207666416102355444464034512896 <type 'long'> 52
a = 1461501637330902918203684832716283019655932542976 <type 'long'> 48
a = 340282366920938463463374607431768211456 <type 'long'> 44
a = 79228162514264337593543950336 <type 'long'> 40
a = 18446744073709551616 <type 'long'> 36
a = 4294967296 <type 'long'> 32
a = 1 <type 'long'> 28
Run Code Online (Sandbox Code Playgroud)
正如你所看到的那样,类型long
在第一次变得太大之后就停留了int
,初始大小为32,但是大小随着值的变化而变化(可以更高或更低[或相等,显然]为32)
所以,为了回答你的问题,基本大小是24 for int
,28 for long
,while long
还有用于保存大值的空间(从4个字节开始 - 因此32个字节long
,但可以根据值上下)
至于你的子问题,为新数字创建一个唯一类型(具有唯一大小)是不可能的,因此Python有"子类" long
类型,它处理一系列数字,因此,一旦超过限制你的旧的long
你必须使用更新的,它也会占更大的数字,因此,它有更多的字节.
归档时间: |
|
查看次数: |
5309 次 |
最近记录: |