Python在存储字符串时如何节省内存

从python3开始,str类型使用unicode来表示,而一个unicode字符最多占用4个字节,具体如何,取决于编码,从内存角度来看,这样的做法是有一些昂贵的。python为了提高性能,节省内存,在其内部,会根据存储的字符不同采用不一样的编码方式:

  1. Latin-1编码,每个字符占1个字节,比如字母a, b, c
  2. UCS-2编码, 每个字符占2个字节,比如汉字
  3. UCS-4编码, 每个字符占4个字节,比如特殊字符emoji '👌🏻'

1. 字符串大小

一下代码在交互式解释器中执行

1.1 空字符串

>>> import sys
>>> s = ''
>>> sys.getsizeof(s)
49

既是是一个空的字符串,也要占用49个字节的内存空间,这些空间用于存储补充信息,例如哈希,长度,字节长度,编码类型和字符串标志

1.2 ascii码表里的字符

>>> s = 'hello'
>>> sys.getsizeof(s)
54
>>> s2 = 'hello world'
>>> sys.getsizeof(s2)
60

s2比s多了6个字符,所占用的空间增加了6个字节,这说明,这些字符只占用一个字节。

1.3 汉字

>>> s = '中'
>>> sys.getsizeof(s)
76
>>> s2 = '中国'
>>> sys.getsizeof(s2)
78

每个汉字占用2个字节的空间

1.4 特殊字符

>>> s = '🐺'
>>> sys.getsizeof(s)
80
>>> s2 = s + '🐝'
>>> sys.getsizeof(s2)
84

2. 定长编码

>>> s = '🐺'
>>> sys.getsizeof(s)
80
>>> s2 = s + 'abc'
>>> sys.getsizeof(s2)
92

字符串s2与s相比,仅仅多了三个ascii码表里的字符abc,但是占用的内存却增加了12,这是因为字符s2里最终包含了一个占用4个字节的字符,因此,字符串里的其他字符也都都占用4个字节。

一个python字符串里的字符,在内存中究竟占用多少字节,根本上取决于字符串里占用字节数最多的那一个,python要保证整个字符串里的每个字符都采取相同长度的编码,这样才能实现对字符串的随机访问,如果每个字符占用字节数不相同,通过索引访问字符串时就不得不遍历字符串,而不是通过索引计算出字符所在的位置,这也正是python内部不使用UTF-8进行编码的原因。

扫描关注, 与我技术互动

QQ交流群: 211426309

加入知识星球, 每天收获更多精彩内容

分享日常研究的python技术和遇到的问题及解决方案