_PyString_Resize重新分配内存吗?

时间:2011-03-22 14:16:09

标签: python c cpython

我正在开发一个Python C扩展模块(用于CPython 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小于buffer_size,它是否使用现有缓冲区重新分配内存?

从效率的角度来看,我可能更喜欢前者避免使用缓冲内容的无用副本,即使它消耗的内存超过了必要的内存。另一方面,重新分配内存也可能会减少内存占用。

那么_PyString_Resize会做哪一个?是否有一种简单的方法来控制这种行为?

1 个答案:

答案 0 :(得分:3)

是的,_PyString_Resize执行realloc - 毕竟,这就是您要求它做的事情: - )

如果要保存重新分配,也许可以read进入堆栈上的缓冲区,然后从中创建字符串对象。像(没有编译和测试,所以把它当作伪代码):

char cbuf[BUFFER_SIZE];
int sz = read(cbuf, BUFFER_SIZE);
PyObject * buffer = PyString_FromStringAndSize(cbuf, sz);

另外,请注意_PyString_ResizeObjects/stringobject.c)的实施上方的警告:

  

以下函数打破了字符串不可变的概念:
  它会改变字符串的大小。我们   只有有了这个才能逃脱   只有一个模块引用了   宾语。你也可以把它想象成创建一个新的字符串对象和   摧毁旧的,只有更有效率。无论如何,请勿使用   如果字符串可能已经为代码的其他部分所知......