python - 为什么 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
- 空字符串的大小不同。
- 在 Python 2 中添加一个字符时需要 4 个额外的字节,而在 Python 3 中只需要一个
为什么两个版本之间的内存占用不同?
编辑
我指定了我的 python 环境的确切版本,因为不同的 Python 3 版本之间存在差异。
解决方案
当然是有原因的,但实际上,这对于任何实际目的都无关紧要。如果您有一个 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 个字节。
推荐阅读
- opengl - OpenGL - 修改纹理参数
- python - (PyQT)当许多元素连接到回调函数时,如何获取哪个元素触发了回调函数?
- c++ - 从派生类访问成员函数的基类指针向量?正确的方法?
- loops - ReadString 读取 EOF 时如何中断循环?
- python - NLTK 不能在带有 KivyMD 的 Android Buildozer 应用程序中工作
- assembly - 具有两个大小为 10 的整数数组 X 和 Y 的汇编程序,其中 Y 包含:如果 X 中的元素为正,则为 1,如果该元素 < = 0,则为 0
- groovy - Groovy,检查数组中的所有元素是否包含子字符串
- python - 如果您之前没有连接到 wifi,如何通过 linux 或 Windows 上的 python 连接到 wifi。(输入:SSID、密码)
- docker-compose - 如何让 docker-compose 使用所选图像主要版本的最新次要版本?
- jquery - 根据窗口宽度添加/删除元素