Rev 4685: Default struct packing is aligning on 4-byte boundaries. in http://bazaar.launchpad.net/~jameinel/bzr/2.1-memory-consumption

John Arbash Meinel john at arbash-meinel.com
Tue Sep 8 22:45:10 BST 2009


At http://bazaar.launchpad.net/~jameinel/bzr/2.1-memory-consumption

------------------------------------------------------------
revno: 4685
revision-id: john at arbash-meinel.com-20090908214456-a9zk4q7gq5anljps
parent: john at arbash-meinel.com-20090908213501-njweb8wujinok4ty
committer: John Arbash Meinel <john at arbash-meinel.com>
branch nick: 2.1-memory-consumption
timestamp: Tue 2009-09-08 16:44:56 -0500
message:
  Default struct packing is aligning on 4-byte boundaries.
  So we don't save any memory by using 'unsigned char' rather than 'long ob_size'
  on 32-bit platforms.
  And conforming to the standard size container means we interoperate better
  with other bits of code.
  We could probably work out 'PACK'ing macros, and do a bit better, though since
  malloc is going to work in certain sizes, it may not matter.
  At a minimum, though, we avoid the 12-bytes of GC object overhead per 'tuple',
  and we certainly avoid the tuple(tuples()) when dealing with parent lists.
-------------- next part --------------
=== modified file 'bzrlib/_keys_type_c.c'
--- a/bzrlib/_keys_type_c.c	2009-09-08 21:35:01 +0000
+++ b/bzrlib/_keys_type_c.c	2009-09-08 21:44:56 +0000
@@ -28,10 +28,13 @@
 #endif
 
 
+/* Because of object alignment, it seems that using unsigned char doesn't make
+ * things any smaller than using an 'int'... :(
+ * Perhaps we should use the high bits for extra flags?
+ */
 typedef struct {
-    PyObject_HEAD
-    unsigned char key_width;
-    unsigned char num_keys; /* Not a Py_ssize_t like most containers */
+    PyObject_VAR_HEAD
+    int key_width;
     PyStringObject *key_strings[1]; /* key_width * num_keys entries */
 } Keys;
 
@@ -42,12 +45,12 @@
 Keys_dealloc(Keys *keys)
 {
     /* Do we want to use the Py_TRASHCAN_SAFE_BEGIN/END operations? */
-    if (keys->num_keys > 0) {
+    if (keys->ob_size > 0) {
         /* tuple deallocs from the end to the beginning. Not sure why, but
          * we'll do the same here.
          */
         int i;
-        for(i = keys->num_keys - 1; i >= 0; --i) {
+        for(i = keys->ob_size - 1; i >= 0; --i) {
             Py_XDECREF(keys->key_strings[i]);
         }
     }
@@ -111,7 +114,7 @@
     }
     self = (Keys *)(type->tp_alloc(type, num_key_bits));
     self->key_width = (unsigned char)key_width;
-    self->num_keys = (unsigned char)num_keys;
+    self->ob_size = (unsigned char)num_keys;
     for (i = 0; i < num_key_bits; i++) {
         obj = PyTuple_GET_ITEM(args, i + 1);
         if (!PyString_CheckExact(obj)) {
@@ -141,7 +144,7 @@
 static Py_ssize_t
 Keys_length(Keys *k)
 {
-    return (Py_ssize_t)k->num_keys;
+    return (Py_ssize_t)k->ob_size;
 }
 
 
@@ -151,7 +154,7 @@
     long start, i;
     PyObject *tpl, *obj;
 
-    if (offset < 0 || offset >= self->num_keys) {
+    if (offset < 0 || offset >= self->ob_size) {
         PyErr_SetString(PyExc_IndexError, "Keys index out of range");
         return NULL;
     }
@@ -191,7 +194,7 @@
     PyObject_HEAD_INIT(NULL)
     0,                                           /* ob_size */
     "Keys",                                      /* tp_name */
-    sizeof(Keys) - sizeof(PyStringObject *),           /* tp_basicsize */
+    sizeof(Keys) - sizeof(PyStringObject *),     /* tp_basicsize */
     sizeof(PyObject *),                          /* tp_itemsize */
     (destructor)Keys_dealloc,                    /* tp_dealloc */
     0,                                           /* tp_print */



More information about the bazaar-commits mailing list