diff options
author | Mark Dickinson <dickinsm@gmail.com> | 2008-12-05 21:55:28 (GMT) |
---|---|---|
committer | Mark Dickinson <dickinsm@gmail.com> | 2008-12-05 21:55:28 (GMT) |
commit | 826f3fefe5d86a5f479a256c535d7f31ce3f88ee (patch) | |
tree | 730042ad37bc53fa34cf202ffc5b49b27fef6d6b /Objects | |
parent | 205e719facb9279e543bdb8d8aa15cef2ed8837b (diff) | |
download | cpython-826f3fefe5d86a5f479a256c535d7f31ce3f88ee.zip cpython-826f3fefe5d86a5f479a256c535d7f31ce3f88ee.tar.gz cpython-826f3fefe5d86a5f479a256c535d7f31ce3f88ee.tar.bz2 |
Issue #4445: save 3 bytes (on average, on a typical machine) per
string allocation.
Diffstat (limited to 'Objects')
-rw-r--r-- | Objects/stringobject.c | 34 |
1 files changed, 21 insertions, 13 deletions
diff --git a/Objects/stringobject.c b/Objects/stringobject.c index 7f30f66..2c365fb 100644 --- a/Objects/stringobject.c +++ b/Objects/stringobject.c @@ -4,6 +4,7 @@ #include "Python.h" #include <ctype.h> +#include <stddef.h> #ifdef COUNT_ALLOCS int null_strings, one_strings; @@ -22,6 +23,14 @@ static PyStringObject *nullstring; */ static PyObject *interned; +/* PyStringObject_SIZE gives the basic size of a string; any memory allocation + for a string of length n should request PyStringObject_SIZE + n bytes. + + Using PyStringObject_SIZE instead of sizeof(PyStringObject) saves + 3 bytes per string allocation on a typical system. +*/ +#define PyStringObject_SIZE (offsetof(PyStringObject, ob_sval) + 1) + /* For both PyString_FromString() and PyString_FromStringAndSize(), the parameter `size' denotes number of characters to allocate, not counting any @@ -74,13 +83,13 @@ PyString_FromStringAndSize(const char *str, Py_ssize_t size) return (PyObject *)op; } - if (size > PY_SSIZE_T_MAX - sizeof(PyStringObject)) { + if (size > PY_SSIZE_T_MAX - PyStringObject_SIZE) { PyErr_SetString(PyExc_OverflowError, "string is too large"); return NULL; } /* Inline PyObject_NewVar */ - op = (PyStringObject *)PyObject_MALLOC(sizeof(PyStringObject) + size); + op = (PyStringObject *)PyObject_MALLOC(PyStringObject_SIZE + size); if (op == NULL) return PyErr_NoMemory(); PyObject_INIT_VAR(op, &PyString_Type, size); @@ -114,7 +123,7 @@ PyString_FromString(const char *str) assert(str != NULL); size = strlen(str); - if (size > PY_SSIZE_T_MAX - sizeof(PyStringObject)) { + if (size > PY_SSIZE_T_MAX - PyStringObject_SIZE) { PyErr_SetString(PyExc_OverflowError, "string is too long for a Python string"); return NULL; @@ -135,7 +144,7 @@ PyString_FromString(const char *str) } /* Inline PyObject_NewVar */ - op = (PyStringObject *)PyObject_MALLOC(sizeof(PyStringObject) + size); + op = (PyStringObject *)PyObject_MALLOC(PyStringObject_SIZE + size); if (op == NULL) return PyErr_NoMemory(); PyObject_INIT_VAR(op, &PyString_Type, size); @@ -992,14 +1001,14 @@ string_concat(register PyStringObject *a, register PyObject *bb) "strings are too large to concat"); return NULL; } - + /* Inline PyObject_NewVar */ - if (size > PY_SSIZE_T_MAX - sizeof(PyStringObject)) { + if (size > PY_SSIZE_T_MAX - PyStringObject_SIZE) { PyErr_SetString(PyExc_OverflowError, "strings are too large to concat"); return NULL; } - op = (PyStringObject *)PyObject_MALLOC(sizeof(PyStringObject) + size); + op = (PyStringObject *)PyObject_MALLOC(PyStringObject_SIZE + size); if (op == NULL) return PyErr_NoMemory(); PyObject_INIT_VAR(op, &PyString_Type, size); @@ -1036,13 +1045,12 @@ string_repeat(register PyStringObject *a, register Py_ssize_t n) return (PyObject *)a; } nbytes = (size_t)size; - if (nbytes + sizeof(PyStringObject) <= nbytes) { + if (nbytes + PyStringObject_SIZE <= nbytes) { PyErr_SetString(PyExc_OverflowError, "repeated string is too long"); return NULL; } - op = (PyStringObject *) - PyObject_MALLOC(sizeof(PyStringObject) + nbytes); + op = (PyStringObject *)PyObject_MALLOC(PyStringObject_SIZE + nbytes); if (op == NULL) return PyErr_NoMemory(); PyObject_INIT_VAR(op, &PyString_Type, size); @@ -3940,7 +3948,7 @@ static PyObject * string_sizeof(PyStringObject *v) { Py_ssize_t res; - res = sizeof(PyStringObject) + v->ob_size * v->ob_type->tp_itemsize; + res = PyStringObject_SIZE + v->ob_size * v->ob_type->tp_itemsize; return PyInt_FromSsize_t(res); } @@ -4179,7 +4187,7 @@ If the argument is a string, the return value is the same object."); PyTypeObject PyString_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) "str", - sizeof(PyStringObject), + PyStringObject_SIZE, sizeof(char), string_dealloc, /* tp_dealloc */ (printfunc)string_print, /* tp_print */ @@ -4275,7 +4283,7 @@ _PyString_Resize(PyObject **pv, Py_ssize_t newsize) _Py_DEC_REFTOTAL; _Py_ForgetReference(v); *pv = (PyObject *) - PyObject_REALLOC((char *)v, sizeof(PyStringObject) + newsize); + PyObject_REALLOC((char *)v, PyStringObject_SIZE + newsize); if (*pv == NULL) { PyObject_Del(v); PyErr_NoMemory(); |