_PyString_Resize реаллок памяти?

1

Я работаю над модулем расширения 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? И есть ли простой способ контролировать такое поведение?

Теги:
cpython

1 ответ

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):

Следующая функция нарушает представление о том, что строки неизменяемы:
он изменяет размер строки. Мы избегайте этого, только если есть только один модуль, ссылающийся на объект. Вы также можете подумать о создании нового строкового объекта и разрушая старый, только более эффективно. В любом случае не используйте это, если строка уже может быть известна какой-либо другой части кода...

Ещё вопросы

Сообщество Overcoder
Наверх
Меню