Re: [PATCH] Reordering interface base initialization



On Wed, 27 Aug 2003, Owen Taylor wrote:

> On Wed, 2003-08-27 at 00:39, Tim Janik wrote:
> > On Wed, 27 Aug 2003, Owen Taylor wrote:

> > what's the point in the lookaside structure?
> > is this all about sparing the initialization state info from
> > IFaceEntry? (the lookaside munching makes your patch buttugly
> > if i may say that ;)
>
> Yeah, it's about making the change not increase the memory consumption
> of GObject. 4 bytes per interface/object pair is sort of marginal
> in terms of "do we care?" It's not too hard for me to imagine an
> app with 300 classes with 10 interfaces each (if you add some
> interfaces to base classes, the interface/object pairs add up quickly.)

if we really worry about size here, it might be better to go for
the bit squeezing then, i.e.:

struct _IFaceEntry
{
  GType           iface_type;
  GTypeInterface *vtable;
};
becomes
struct _IFaceEntry
{
  GType   iface_type;
  gulong  mfield;    /* field used to store a vtable pointer and two flags */
};
#define	IFACE_ENTRY_GET_BITS(ie)     (ie->mfield & 3)
#define	IFACE_ENTRY_SET_BITS(ie,b)   (ie)->mfield = ((ie)->mfield & ~(gulong) 3) | (b)
#define	IFACE_ENTRY_GET_VTABLE(ie)   ((GTypeInterface*) ((ie)->mfield & ~(gulong) 3))
#define	IFACE_ENTRY_SET_VTABLE(ie,v) (ie)->mfield = IFACE_ENTRY_GET_BITS (ie) | (gulong) (v)

i'd say using 4 set/get macros involves less hackery
than the lookaside aproach (and certainly less code).

> > > +  init_info.init_node = node;
> > > +  if (CLASSED_NODE_N_IFACES (node) > MAX_STACK_IFACE_STATES)
> > > +    init_info.iface_states = g_malloc (CLASSED_NODE_N_IFACES (node));
> > > +  else
> > > +    init_info.iface_states = stack_iface_states;
> >
> > for what it's worth (since i don't like the lookaside stuff anyways),
> > you could have made your code a good deal simpler just for forgoing
> > the stack allocation here. class/iface initialization isn't as time
> > critical or frequently called, that a single malloc would make a
> > difference (and if it were, the g_slist_prepend() you use would
> > be potentially way more offending).
>
> A) g_slist_prepend() is pretty much free with the free lists.

a quick test shows it's about 40%-50% the time of a single malloc()
on average, depending on the machine you use. mostly, that's due to:
a) we have to acquire a lock for each node allocation, just like
   malloc() has to. having something like GAtomicPointer could
   definitely help here
b) malloc() amounts to a somewhat more sophisticated free-list readout
   as well on average.

> B) The code doesn't get that much simpler without the stack allocation;
>    most of the extra complexity is in code paths that never get hit
>    as well. If you used GByteArray, then it gets easier, but two
>    extra mallocs..
> C) I think saving a couple of hundred malloc/frees on app startup
>    is worth thinking about. Marginally worth thinking about, but'
>    worth thinking about.

i don't think so. if you initialize hundreds of classes at app
startup you'll definitely use your time somewhere else. a 100
small-sized mallocs amount to less than a 100 microseconds on
on a moderately fast machine.

> In terms of what exact degree of optimization/simplicity tradeoff we
> pick, I don't think it matters a whole lot. Can always fix up based on
> profiling later.
>
> Regards,
> 						Owen
>

---
ciaoTJ




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]