字符串对象

字符串对象是不可变对象,使得字符串对象可以作为dict的键值,但是也使得一些字符串操作的效率大大降低,例如多个字符串的连接操作。

typedef struct {
  PyObject_VAR_HEAD
  long ob_shash;
  int ob_sstate;
  char ob_sval[1];
 } PyStringObject;

可变对象有一个ob_size保存包含对象的个数,ob_shash就是该字符串对象的hash值,避免重复计算,ob_sval虽然看起来是一个字符数组,实际上是作为一个字符串指针来使用的,指向的是一个ob_size + 1的内存,且ob_sval[ob_size] = '\0',ob_sstate则说明该对象是否经过了intern机制的处理(hash 和 intern机制可提升虚拟机的运行效率 20%),默认:op->ob_shash = -1;op->ob_sstate = SSTATE_NOT_INTERNED

字符串对象创建

PyString_FromString(const char *str)

对于正常的字符串则分配内存,然后复制str的值到新分配的内存中,完毕

PyString_FromStringAndSize(const char *str, int size)

这个函数接受的str可以不用'\0'结尾,具体大小直接按size决定

字符串intern

对空字符串和单字符串的处理

在完成字符串创建之后,对空字符串有一个特殊处理,即当传入的str为一个'\0'的字符串,则都指向python内部已经创建好的nullstring对象;对数组长度为1的,即传入的是'A\0'这样的字符串,放入characters数组中

处理结果:空字符串和单字符 这两种string对象在python运行中持久化

对普通字符串的处理

利用一个名称为interned的dict,来实现名称相同的字符串不用重复在内存中创建,但实现的逻辑为:

仍然创建该字符串对象,然后以该字符串对象为key在dict中查找,如果找到,则把新创建的字符串对象删除,使用原来的,增加引用计数即可

字符串连接

每两个字符串连接,会计算两个字符串的长度和,分配内存,然后复制,如果是n个字符串连接会执行n-1次分配内存再复制的操作,低效

使用join操作,则把列表中的所有字符串取出长度,分配一次内存,然后复制,高效

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容