我正在开发一个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/

10-11 22:50
查看更多