首页 > 解决方案 > 为什么 Unicode 字符串在 Python 2 和 3 中具有不同的内存占用?

问题描述

在 Python 2 中,一个空字符串正好占用 37 个字节,

>>>> print sys.getsizeof('')
37

在 Python 3.6 中,相同的调用将输出 49 个字节,

>>>> print(sys.getsizeof(''))
49

现在我认为这是因为在 Python 3 中,所有字符串现在都是 Unicode。但是,令我惊讶的是,这里有一些令人困惑的输出,

蟒蛇 2.7

>>>> print sys.getsizeof(u'')
52
>>>> print sys.getsizeof(u'1')
56

蟒蛇 3.6

>>>>print(sys.getsizeof(''))
49
>>>>print(sys.getsizeof('1'))
50
  1. 空字符串的大小不同。
  2. 在 Python 2 中添加一个字符时需要 4 个额外的字节,而在 Python 3 中只需要一个

为什么两个版本之间的内存占用不同?

编辑

我指定了我的 python 环境的确切版本,因为不同的 Python 3 版本之间存在差异。

标签: pythonpython-3.xpython-2.7memoryunicode

解决方案


当然是有原因的,但实际上,这对于任何实际目的都无关紧要。如果您有一个 Python 系统,其中您必须在内存中保留如此多的字符串以接近系统内存,您应该通过 (1) 尝试在内存中延迟加载/创建字符串或 (2) 使用一个字节来优化它面向高效的二进制结构来处理你的数据,比如 Numpy 提供的,或者 Python 自己的bytearray.

空字符串文字(来自 Py2 的 unicode 文字)的更改可能与您正在查看的版本之间的任何实现细节有关,即使编写 C 代码以直接与 Python 字符串交互也不重要:即使那些应该只触及字符串通过 API。

现在,为什么 Python 3 中的字符串仅将其大小增加“1”字节,而在 Python 2 中将大小增加 4 个字节的具体原因是PEP 393

在 Python 3.3 之前,Python 中的任何(unicode)字符串都会为每个字符使用固定的 2 个字节或固定的 4 个字节的内存——并且使用本机代码的 Python 解释器和 Python 模块必须被编译为仅使用其中一种。IE 你实际上可能有不兼容的 Python 二进制文件,即使版本匹配,由于在构建时选择的字符串宽度选项 - 构建被称为“窄构建”和“宽构建”。使用上述 PEP 391,Python 字符串在实例化时确定其字符大小,具体取决于它包含的最宽 unicode 代码点的大小。包含前 256 个代码点(相当于 Latin-1 字符集)中包含的点的字符串每个字符仅使用 1 个字节。


推荐阅读