手机网站建设模板,wordpress图片上传卡住,wordpress 在线商城,苏州网络公司排名Python字符串驻留技术 1.什么是字符串驻留2. 为什么要驻留字符串3. Python的字符串驻留4. Python 字符驻留原理4.1 如何驻留字符串4.2 如何清理驻留的字符串 5. 字符串驻留的实现5.1. 变量、常量与函数名5.2 字典的键5.3 任何对象的属性5.4 显式地驻留 6 字符串驻留的其他发现 … Python字符串驻留技术 1.什么是字符串驻留2. 为什么要驻留字符串3. Python的字符串驻留4. Python 字符驻留原理4.1 如何驻留字符串4.2 如何清理驻留的字符串 5. 字符串驻留的实现5.1. 变量、常量与函数名5.2 字典的键5.3 任何对象的属性5.4 显式地驻留 6 字符串驻留的其他发现 由于字符串是任何编程语言中不可或缺的一个部分因此如果有快速操作字符串的能力就有可以迅速的提高整体的性能。 本文我们将深入研究Python 的内部实现并了解 Python如何使用一种名为字符串驻留 string Interning的技术实现解释器的高性能。以下是本文的提纲 1.什么是字符串驻留
字符串驻留是编译器/解释器的优化方法它通过 缓存一般性的字符串从而节省字符串处理任务的空间和时间。 事实上这种优化方法不会每次都创建一个新的 字符串副本而是仅为每个适当的不可变值保留一个字符串副本并使用指针引用之。string interning 一般译为 “ 字符串驻留或字符串留用” 在某些 语言中可能习惯使用 string pool 字符串常量池的概念其实这是对同一种机制的不同表述。
2. 为什么要驻留字符串
首先字符串驻留提升了字符串比较的速度。 如果没有驻留当我们要比较两个字符串是否相等时它的时间复杂度将会上升到 o(n) 即需要检查两个字符串中的每个字符才能判断他们是否相等。但是如果两个字符串使用的是同一个对象的引用那么我们只需要判断检查指针是否相同就足以判断出两个字符串是否相同不需要逐一检查每个字符串。字符串驻留技术减少了内存占用Python避免内存中 充斥多余的字符串对象通过享元设计模式共享和重用已经定义的对象从而优化内存占用。
3. Python的字符串驻留
在Python中使用 is 运算符 检查两个对象是否引用同一个内存对象。注意在 Python3.8 版本之后需要使用 来判断两个对象是否相等。
python python # true
12 # false
Python python # false4. Python 字符驻留原理
在 CPython 中字符串的引用被一个名为 interned 的 python字典所存储访问和管理。该字典在第一调用字符串驻留时被延迟的初始化并持有全部已驻留字符串对象的引用。
4.1 如何驻留字符串
在 CPython 中负责驻留字符串的核心函数是 PyUnicode_InternInplace 它定义在 unicodeobject.c 中当调用时它会创建一个准备容纳所有驻留字符串的字典 Interned , 然后登记入参中的对象然后另其键和值都使用相同的对象引用
void PyUnicode_InternInplace(PyObject **p)
{PyObject *s p;........// Lazing build the dicrionary to hold interned stringsif (interned NULL) {interned PyDict_New();if (interned NULL){PyErr_Clear();return;}}PyObject *t;// make an entry to the interned dictionary for the given objectt PyDict_SetDefault(interned, s, s);......// set the state of the string to be INTERNED_PyUnicode_STATE(s).interned SSTATE_INTERNED_MORTAL;
}4.2 如何清理驻留的字符串
清理函数从 interned 字典中遍历所有的字符串调整这些对象的引用计数并把它们标记为 NOT_INTERNED 使其被垃圾回收一旦所有的字符串被标记为 NOT_INTERNED则 interned 字典会被清空并删除。
这个清理函数就是 _PyUnicode_ClearInterned 在 unicodeobject.c 中定义
void _PyUnicode_ClearInterned(PyThreadState *tstate)
{// Get all the keys to the interned dictionaryPyObject *keys PyDict_Keys(interned);.......// Interned Unicode strings are not forcibly deallocated// rather ,we give them their stolen references back// and then clear and DECREF the interned dictfor(Py_ssize_t i 0; i n; i){PyObject *s PyList_GET_ITEM(keys,i);.....switch (PyUnicode_CHECK_INTERNED(s)){case SSTATE_INTERNED_IMMORTAL:Py_SET_REFCNT(s,Py_REFCNT(s)1);break;case SSTATE_INTERNED_MORTAL:// Restore the two references(key and balue) ignored// by PyUnicode_InterInPlace()Py_SET_REFCNT(s,Py_REFCNT(s) 2);break;case SSTATE_NOTINTERNED:default:Py_UNREACHABLE();}// making the string to be NOT_INTERNED_PyUnicode_STATE(s).interned SSTATE_NOT_INTERNED;}// decreasing the refernece to the initialized and// access可以是objectPy_DECREF(keys);// clearing the dictionaryPyDict_Clear(interned);// clearing the object internedPy_CLEAR(interned);
}5. 字符串驻留的实现
这一小节主要讲Python会驻留哪些字符串
5.1. 变量、常量与函数名
CPython 对常量例如函数名变量名字符串字面量等执行字符串驻留。
5.2 字典的键
CPthon 还会驻留任何字典对象的字符串键
5.3 任何对象的属性
CPython中对象的属性可以通过 setattr 函数显式地设置也可以作为类成员的一部分隐式的设置或者在其数据类型中定义。 CPython会驻留所有这些属性名以便实现快速的查找。
5.4 显式地驻留
Python还支持通过 sys模块中的 intern 函数进行显示地字符串驻留。
6 字符串驻留的其他发现
只有在编译期的字符串会被驻留咋解释时或编译时指定的字符串会被驻留而动态创建的字符串则不会