summaryrefslogtreecommitdiffstats
path: root/Objects
diff options
context:
space:
mode:
authorMark Dickinson <dickinsm@gmail.com>2008-12-05 21:55:28 (GMT)
committerMark Dickinson <dickinsm@gmail.com>2008-12-05 21:55:28 (GMT)
commit826f3fefe5d86a5f479a256c535d7f31ce3f88ee (patch)
tree730042ad37bc53fa34cf202ffc5b49b27fef6d6b /Objects
parent205e719facb9279e543bdb8d8aa15cef2ed8837b (diff)
downloadcpython-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.c34
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();