Skip to content

Commit 3c6127d

Browse files
jimmodpgeorge
authored andcommitted
py/objnamedtuple: Optimise slot RAM usage for namedtuple.
Rather than reserving a full 12-slot mp_obj_type_t, reserve enough room for seven and cast as necessary. Signed-off-by: Jim Mussared <[email protected]>
1 parent 165388e commit 3c6127d

File tree

2 files changed

+16
-16
lines changed

2 files changed

+16
-16
lines changed

py/objnamedtuple.c

+13-12
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ STATIC mp_obj_t namedtuple_make_new(const mp_obj_type_t *type_in, size_t n_args,
104104
#elif MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_DETAILED
105105
mp_raise_msg_varg(&mp_type_TypeError,
106106
MP_ERROR_TEXT("%q() takes %d positional arguments but %d were given"),
107-
type->base.name, num_fields, n_args + n_kw);
107+
((mp_obj_type_t *)&type->base)->name, num_fields, n_args + n_kw);
108108
#endif
109109
}
110110

@@ -153,17 +153,18 @@ mp_obj_namedtuple_type_t *mp_obj_new_namedtuple_base(size_t n_fields, mp_obj_t *
153153

154154
STATIC mp_obj_t mp_obj_new_namedtuple_type(qstr name, size_t n_fields, mp_obj_t *fields) {
155155
mp_obj_namedtuple_type_t *o = mp_obj_new_namedtuple_base(n_fields, fields);
156-
o->base.base.type = &mp_type_type;
157-
o->base.flags = MP_TYPE_FLAG_EQ_CHECKS_OTHER_TYPE; // can match tuple
158-
o->base.name = name;
159-
o->base.make_new = namedtuple_make_new;
160-
MP_OBJ_TYPE_SET_SLOT(&o->base, print, namedtuple_print, 0);
161-
MP_OBJ_TYPE_SET_SLOT(&o->base, unary_op, mp_obj_tuple_unary_op, 1);
162-
MP_OBJ_TYPE_SET_SLOT(&o->base, binary_op, mp_obj_tuple_binary_op, 2);
163-
MP_OBJ_TYPE_SET_SLOT(&o->base, attr, namedtuple_attr, 3);
164-
MP_OBJ_TYPE_SET_SLOT(&o->base, subscr, mp_obj_tuple_subscr, 4);
165-
MP_OBJ_TYPE_SET_SLOT(&o->base, getiter, mp_obj_tuple_getiter, 5);
166-
MP_OBJ_TYPE_SET_SLOT(&o->base, parent, &mp_type_tuple, 6);
156+
mp_obj_type_t *type = (mp_obj_type_t *)&o->base;
157+
type->base.type = &mp_type_type;
158+
type->flags = MP_TYPE_FLAG_EQ_CHECKS_OTHER_TYPE; // can match tuple
159+
type->name = name;
160+
type->make_new = namedtuple_make_new;
161+
MP_OBJ_TYPE_SET_SLOT(type, print, namedtuple_print, 0);
162+
MP_OBJ_TYPE_SET_SLOT(type, unary_op, mp_obj_tuple_unary_op, 1);
163+
MP_OBJ_TYPE_SET_SLOT(type, binary_op, mp_obj_tuple_binary_op, 2);
164+
MP_OBJ_TYPE_SET_SLOT(type, attr, namedtuple_attr, 3);
165+
MP_OBJ_TYPE_SET_SLOT(type, subscr, mp_obj_tuple_subscr, 4);
166+
MP_OBJ_TYPE_SET_SLOT(type, getiter, mp_obj_tuple_getiter, 5);
167+
MP_OBJ_TYPE_SET_SLOT(type, parent, &mp_type_tuple, 6);
167168
return MP_OBJ_FROM_PTR(o);
168169
}
169170

py/objnamedtuple.h

+3-4
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,9 @@
2929
#include "py/objtuple.h"
3030

3131
typedef struct _mp_obj_namedtuple_type_t {
32-
// Must use the full-size version to avoid this being a variable sized member.
33-
// This means that named tuples use slightly more RAM than necessary, but
34-
// no worse than if we didn't have slots/split representation.
35-
mp_obj_full_type_t base;
32+
// This is a mp_obj_type_t with seven slots.
33+
mp_obj_empty_type_t base;
34+
void *slots[7];
3635
size_t n_fields;
3736
qstr fields[];
3837
} mp_obj_namedtuple_type_t;

0 commit comments

Comments
 (0)