gh-129813, PEP 782: Add PyBytesWriter.overallocate (#138941)

Disable overallocation in _PyBytes_FormatEx() at the last write.
This commit is contained in:
Victor Stinner 2025-09-15 23:15:32 +01:00 committed by GitHub
parent 4554486f15
commit 4e00e2504f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 21 additions and 9 deletions

View file

@ -147,6 +147,15 @@ PyAPI_FUNC(void*) _PyBytesWriter_WriteBytes(_PyBytesWriter *writer,
PyAPI_FUNC(PyBytesWriter*) _PyBytesWriter_CreateByteArray( PyAPI_FUNC(PyBytesWriter*) _PyBytesWriter_CreateByteArray(
Py_ssize_t size); Py_ssize_t size);
struct PyBytesWriter {
char small_buffer[256];
PyObject *obj;
Py_ssize_t size;
int use_bytearray;
int overallocate;
};
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View file

@ -836,6 +836,11 @@ _PyBytes_FormatEx(const char *format, Py_ssize_t format_len,
if (v == NULL) if (v == NULL)
goto error; goto error;
if (fmtcnt == 0) {
/* last write: disable writer overallocation */
writer->overallocate = 0;
}
sign = 0; sign = 0;
fill = ' '; fill = ' ';
switch (c) { switch (c) {
@ -1056,6 +1061,10 @@ _PyBytes_FormatEx(const char *format, Py_ssize_t format_len,
assert((res - before) == alloc); assert((res - before) == alloc);
#endif #endif
} /* '%' */ } /* '%' */
/* If overallocation was disabled, ensure that it was the last
write. Otherwise, we missed an optimization */
assert(writer->overallocate || fmtcnt == 0 || use_bytearray);
} /* until end */ } /* until end */
if (argidx < arglen && !dict) { if (argidx < arglen && !dict) {
@ -3746,14 +3755,6 @@ _PyBytes_Repeat(char* dest, Py_ssize_t len_dest,
// --- PyBytesWriter API ----------------------------------------------------- // --- PyBytesWriter API -----------------------------------------------------
struct PyBytesWriter {
char small_buffer[256];
PyObject *obj;
Py_ssize_t size;
int use_bytearray;
};
static inline char* static inline char*
byteswriter_data(PyBytesWriter *writer) byteswriter_data(PyBytesWriter *writer)
{ {
@ -3802,7 +3803,8 @@ byteswriter_resize(PyBytesWriter *writer, Py_ssize_t size, int overallocate)
return 0; return 0;
} }
if (overallocate && !writer->use_bytearray) { overallocate &= writer->overallocate;
if (overallocate) {
if (size <= (PY_SSIZE_T_MAX - size / OVERALLOCATE_FACTOR)) { if (size <= (PY_SSIZE_T_MAX - size / OVERALLOCATE_FACTOR)) {
size += size / OVERALLOCATE_FACTOR; size += size / OVERALLOCATE_FACTOR;
} }
@ -3867,6 +3869,7 @@ byteswriter_create(Py_ssize_t size, int use_bytearray)
writer->obj = NULL; writer->obj = NULL;
writer->size = 0; writer->size = 0;
writer->use_bytearray = use_bytearray; writer->use_bytearray = use_bytearray;
writer->overallocate = !use_bytearray;
if (size >= 1) { if (size >= 1) {
if (byteswriter_resize(writer, size, 0) < 0) { if (byteswriter_resize(writer, size, 0) < 0) {