Python 中的一切都是对象。所以 Python 中 int 的大小会比平时大。
>>> sys.getsizeof(int())
24
好的,但是为什么 2⁶³
比 2⁶³ - 1
还要多 12 个字节,而不仅仅是一个?
>>> sys.getsizeof(2**63)
36
>>> sys.getsizeof(2**62)
24
我知道 2⁶³
是 long 而 2⁶³-1
是 int,但为什么会有 12 个字节的差异?
没有更直观的,我尝试了一些其他的东西:
>>> a = 2**63
>>> a -= 2**62
>>> sys.getsizeof(a)
36
a
仍以 long 形式存储,即使它现在可以存储在 int 中。所以这并不奇怪。但是:
>>> a -= (2**63 - 1)
>>> a = 2**63
>>> a -= (2**63 - 1)
>>> a
1L
>>> sys.getsizeof(a)
28
新尺寸。
>>> a = 2**63
>>> a -= 2**63
>>> a
0L
>>> sys.getsizeof(a)
24
回到 24 字节,但仍然是 long。
我得到的最后一件事:
>>> sys.getsizeof(long())
24
问题:
内存存储在这些场景中是如何工作的?
子问题:
为什么要加上我们直觉告诉我们的只有 1 位,会有 12 个字节的间隙?
为什么int()
和long()
都是24字节,而long(1)
已经是28字节而int (2⁶²)
?
注意:Python 3.X 的工作方式有点不同,但不是更直观。在这里,我专注于 Python 2.7;我没有测试以前的版本。
最佳答案
why does it get 12 more bytes for 2⁶³ compared too 2⁶³ - 1 and not just one?
在 LP64 上系统1,一个 Python 2 int
consists of正好三个指针大小的片段:
- 类型指针
- 引用计数
- 实际值,一个 C
long int
总共 24 个字节。另一方面,Python long
consists of :
- 类型指针
- 引用计数
- 位数,指针大小的整数
- 值位的内联数组,每个包含 30 位值,但以 32 位单元存储(其中一个未使用的位在加法和减法期间用于 efficient carry/borrow)
2**63 需要 64 位来存储,因此它适合三个 30 位数字。由于每个数字是 4 个字节宽,整个 Python long
将占用 24+3*4 = 36 个字节。
换句话说,区别在于 long
必须单独存储数字的大小(8 个额外字节),并且存储值的空间效率略低(12 个字节到存储 2**63 的数字)。包括大小,long
中的值2**63占用20个字节。将其与简单 int
的 any 值占用的 8 个字节进行比较,得到观察到的 12 个字节的差异。
值得注意的是,Python 3 只有一种整数类型,称为int
,它是可变宽度的,实现方式与Python 2 long
相同。
1 64 位 Windows 的不同之处在于它保留了 32 位
long int
,大概是为了与使用 char
、short< 的大量旧代码的源代码兼容
和 long
作为 8、16 和 32 位值的“方便”别名,恰好适用于 16 位和 32 位系统。要在 x86-64 Windows 上获得实际的 64 位类型,必须使用 __int64
或(在较新的编译器版本上)long long
或 int64_t
.由于 Python 2 内部依赖于 Python int
在各个地方适合 C long,因此 sys.maxint
仍然是 2**31-1
,甚至在 64 位 Windows 上。这个怪癖在 Python 3 中也得到了修复,它没有 maxint 的概念。
关于python - 为什么2⁶³的大小是36字节,而2⁶³-1只有24字节?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49153714/