You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
String allocations waste 3 bytes of memory on average. #48695
There are a number of places in Objects/stringobject.c where memory is
allocated for a string of length n using:
PyObject_MALLOC(sizeof(PyStringObject) + n)
On my computer (OS X 10.5.5/Intel), and, I suspect, on most common
platforms, the PyStringObject struct is going to contain some number of
bytes (probably 3) of trailing padding; the result is that the
PyObject_MALLOC call above asks for 3 more bytes than are necessary, and
on average the Python interpreter will waste 3 bytes of memory per string
allocation. Is there any reason not to replace these calls with:
PyObject_MALLOC(offsetof(PyStringObject, ob_sval) + n + 1)
+1 on the idea. -1 on the current patch. Can you encapsulate this in a
simpler macro? I find the proposed replacement to be cryptic and
error-prone (i.e. hard to mentally verify its correctness and somewhat
likely to be screwed-up by a future maintainer).
Why is +1 required here? If I understand offsetof() correctly than it
returns the position of the ob_sval element. Shouldn't PyStringObject +
offsetof(PyStringObject, ob_sval) point to the first element of the
ob_svall array?
The +1 is there for the trailing null byte on the string: if s is a
Python string with len(s) == n, then the ob_sval array needs space for n+1
characters.
Activity
mdickinson commentedon Nov 27, 2008
There are a number of places in Objects/stringobject.c where memory is
allocated for a string of length n using:
PyObject_MALLOC(sizeof(PyStringObject) + n)
On my computer (OS X 10.5.5/Intel), and, I suspect, on most common
platforms, the PyStringObject struct is going to contain some number of
bytes (probably 3) of trailing padding; the result is that the
PyObject_MALLOC call above asks for 3 more bytes than are necessary, and
on average the Python interpreter will waste 3 bytes of memory per string
allocation. Is there any reason not to replace these calls with:
PyObject_MALLOC(offsetof(PyStringObject, ob_sval) + n + 1)
instead?
Patch attached.
mdickinson commentedon Nov 27, 2008
Updated patch: fix overflow checks to use offsetof instead of sizeof as
well.
rhettinger commentedon Nov 27, 2008
+1 on the idea. -1 on the current patch. Can you encapsulate this in a
simpler macro? I find the proposed replacement to be cryptic and
error-prone (i.e. hard to mentally verify its correctness and somewhat
likely to be screwed-up by a future maintainer).
rhettinger commentedon Nov 27, 2008
Suggestion:
mdickinson commentedon Nov 28, 2008
Yep. That works nicely.
Here's a revised patch.
tiran commentedon Nov 28, 2008
Why is +1 required here? If I understand offsetof() correctly than it
returns the position of the ob_sval element. Shouldn't PyStringObject +
offsetof(PyStringObject, ob_sval) point to the first element of the
ob_svall array?
mdickinson commentedon Nov 28, 2008
The +1 is there for the trailing null byte on the string: if s is a
Python string with len(s) == n, then the ob_sval array needs space for n+1
characters.
tiran commentedon Nov 28, 2008
Ah! I forgot the trailing \0 byte ... Thanks Mark!
mdickinson commentedon Nov 28, 2008
Hmmm. test_sys fails on 64-bit build.
Patch updated to fix this.
All tests now pass on 32-bit and 64-bit, debug and non-debug builds.
rhettinger commentedon Nov 29, 2008
Looks much cleaner.
mdickinson commentedon Dec 5, 2008
Applied to the trunk in r67601. Will merge to other branches if the
buildbots look okay.
mdickinson commentedon Dec 6, 2008
Applied to py3k in r67610.