我正在开发一个Python C扩展模块(用于C Python 2.5)。它调用一些底层网络API来填充缓冲区。
目前编写的代码基本如下:
PyObject * buffer;
char * cbuf;
size_t buffer_size = 1024;
int sz;
buffer = PyString_FromStringAndSize(NULL, buffer_size);
if (buffer == NULL) return NULL;
cbuf = PyString_AsString(buffer);
Py_BEGIN_ALLOW_THREADS
sz = read(cbuf, buffer_size);
Py_END_ALLOW_THREADS
if (sz > 0 && sz != buffer_size && _PyString_Resize(&buffer, sz) < 0)
return NULL;
据我所知,这段代码运行良好,但我想知道
_PyString_Resize
的内部机制。如果SZ小于BuffelyStand,它是否使用它重新分配内存的现有缓冲区?从效率的角度来看,我可能更喜欢前者,以避免无用的缓冲区内容拷贝,即使它消耗的内存超过必要的容量。另一方面,重新分配内存也可能会减少内存占用。
那么PyString调整的是哪一个呢?有没有简单的方法来控制这种行为?
最佳答案
是的,_PyString_Resize
会的-毕竟,这是你让它做的:-)
如果要保存重新分配,也许可以将realloc
保存到堆栈上的缓冲区中,然后从中创建string对象。类似于(未编译和测试,因此将其视为伪代码):
char cbuf[BUFFER_SIZE];
int sz = read(cbuf, BUFFER_SIZE);
PyObject * buffer = PyString_FromStringAndSize(cbuf, sz);
另外,请注意
read
实现上面的警告(它在_PyString_Resize
中):以下函数打破了字符串是不可变的概念:
它改变了字符串的大小。我们
只有在有机会
只有一个模块引用
目标您还可以考虑ITA创建一个新的字符串对象并
摧毁旧的,只会更有效率。无论如何,不要使用
如果字符串可能已经被代码的其他部分知道。。。
关于python - _PyString_Resize是否重新分配内存?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/5392657/