mirror of
https://github.com/python/cpython.git
synced 2026-01-06 15:32:22 +00:00
Update `bytearray` to contain a `bytes` and provide a zero-copy path to "extract" the `bytes`. This allows making several code paths more efficient. This does not move any codepaths to make use of this new API. The documentation changes include common code patterns which can be made more efficient with this API. --- When just changing `bytearray` to contain `bytes` I ran pyperformance on a `--with-lto --enable-optimizations --with-static-libpython` build and don't see any major speedups or slowdowns with this; all seems to be in the noise of my machine (Generally changes under 5% or benchmarks that don't touch bytes/bytearray). Co-authored-by: Victor Stinner <vstinner@python.org> Co-authored-by: Maurycy Pawłowski-Wieroński <5383+maurycy@users.noreply.github.com>
38 lines
1.4 KiB
C
38 lines
1.4 KiB
C
#ifndef Py_CPYTHON_BYTEARRAYOBJECT_H
|
|
# error "this header file must not be included directly"
|
|
#endif
|
|
|
|
/* Object layout */
|
|
typedef struct {
|
|
PyObject_VAR_HEAD
|
|
/* How many bytes allocated in ob_bytes
|
|
|
|
In the current implementation this is equivalent to Py_SIZE(ob_bytes_object).
|
|
The value is always loaded and stored atomically for thread safety.
|
|
There are API compatibilty concerns with removing so keeping for now. */
|
|
Py_ssize_t ob_alloc;
|
|
char *ob_bytes; /* Physical backing buffer */
|
|
char *ob_start; /* Logical start inside ob_bytes */
|
|
Py_ssize_t ob_exports; /* How many buffer exports */
|
|
PyObject *ob_bytes_object; /* PyBytes for zero-copy bytes conversion */
|
|
} PyByteArrayObject;
|
|
|
|
/* Macros and static inline functions, trading safety for speed */
|
|
#define _PyByteArray_CAST(op) \
|
|
(assert(PyByteArray_Check(op)), _Py_CAST(PyByteArrayObject*, op))
|
|
|
|
static inline char* PyByteArray_AS_STRING(PyObject *op)
|
|
{
|
|
return _PyByteArray_CAST(op)->ob_start;
|
|
}
|
|
#define PyByteArray_AS_STRING(self) PyByteArray_AS_STRING(_PyObject_CAST(self))
|
|
|
|
static inline Py_ssize_t PyByteArray_GET_SIZE(PyObject *op) {
|
|
PyByteArrayObject *self = _PyByteArray_CAST(op);
|
|
#ifdef Py_GIL_DISABLED
|
|
return _Py_atomic_load_ssize_relaxed(&(_PyVarObject_CAST(self)->ob_size));
|
|
#else
|
|
return Py_SIZE(self);
|
|
#endif
|
|
}
|
|
#define PyByteArray_GET_SIZE(self) PyByteArray_GET_SIZE(_PyObject_CAST(self))
|