【Python旧时笔记 三】Python的字符串对象

PyStringObject定义在stringobject.h中,附有不少注释说明。
1. PyStringObject实际上是一组字符,以'\0'结尾,且因为有只是长度的变量,所以也可以包含'\0'作为内容。
2. PyStringObject是不可变对象,所以a = "hello"和a = "world"先后执行后,a指向的是不同的对象了。
3. PyStringObject保存了hash值避免重复计算。
4. 采用intern机制来处理相同的字符串对象。

结构体定义如下:
typedefstruct{
PyObject_VAR_HEAD //不定长对象
longob_shash; //如果还没计算,为-1
intob_sstate; //如果该字符串在interned字典中,则该标志不为0。而且在这种情况下,两个来自interned字典的引用不算进ob_refcnt
charob_sval[1]; //用来作为指针指向保存字符串的内存区域,包含ob_size+1个元素
}PyStringObject;

计算哈希值的算法有必要MARK下,以后可以参考使用。
staticlong
string_hash(PyStringObject*a)
{
registerPy_ssize_tlen;
registerunsignedchar*p;
registerlongx;

if(a->ob_shash!= -1)
returna->ob_shash;
len=Py_SIZE(a);
p= (unsignedchar*)a->ob_sval;
x= *p<< 7;
while(--len>= 0)
x= (1000003*x) ^ *p++;
x^=Py_SIZE(a);
if(x== -1)
x= -2;
a->ob_shash=x;
returnx;
}



intern机制是用来确保相同的值的字符串对象只有一个存在,并且使得比较操作可以仅仅通过指针比较来完成。
它实际上是维护了一个字典(dict/map)interned,当字符串被interned时,会查找字典中键的存在,如果没有则放入。
这种方法可以在空间上节省,并不能节省时间,因为要判断是否存在于interned字典中,需要先创建字符串对象,才能去表中查找。
此外,这种方法默认针对Python的关键字、单字符、空串等。
当然,Python也提供了intern()内置函数来缓存用户想要的字符串对象。
缓存hash值以及intern机制为解释器加速了20%。

最后,是关于字符串的连接。
比如:str = str1 + str2 + str3 + str4,由于PyStringObject is immutable,所以会为3个+号执行3次内存的分配和复制
而如果将待连接的字符串放入可迭代对象中,使用string_join(PyStringObject的join操作),就会一次计算所需的总共内存大小,一次分配,然后再全部复制过去。


JasonLee 2011.08.08 0:33
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值