Re: Performance data for nautilus



On Fri, 18 Oct 2002, Alexander Larsson wrote:

> On Wed, 16 Oct 2002, Anand Subramanian wrote:

> > On a sequel to the gedit performance data, we are attaching the
> > performance report for nautilus.

> Very interesting. As usual it shows up GObject at its worst.

i don't think this is a particularly fair comment to make for the
performance data you posted.

>   * *********************************************************
>   *  Function:                      g_type_check_instance_is_a
>   *  Called:                          1106240 times
>   *  Function time:                 121654830 cycles ( 2.25% of .root.)
>   *  Function+descendants time:     344618647 cycles ( 6.37% of .root.)

this makes up an average of 110 cycles function time and 312 cycles
f+d time for g_type_check_instance_is_a(). i don't think that's much
for a type check, for the non-interface case, it really doesn't do
anymore than check and dereference a couple pointers.
it's the sheer amount of times (more than a million) this function
is being called which makes it a significant profile item. and that's
not amazing to me either, considering the convention to prefix every
function with:
  g_return_if_fail (FOO_IS_OBJECT (foo));
where every *_IS_*() boils down to a call to g_type_check_instance_is_a().

>   *  Distribution to Callers:
>   *    203845 times (18.63% of f+d time) g_object_ref
>   *    210290 times (19.22% of f+d time) g_object_unref
>   * *********************************************************
>
> It seems a full 2.4% of the nautilus execution time is spent making sure
> that what you pass to g_object_ref/unref() is actually GObjects.
> I'm not sure it's really worth that. Maybe we should change G_IS_OBJECT to
> g_type_fundamental (((GTypeInstance *)(instance))->g_class->g_type) ==
> G_TYPE_OBJECT.

boom, segfault. in case instance==NULL, or instance->g_class == NULL. two
frequent cases intended to be caught by the *_IS_*() macros. so if at all,
you better make this:
  g_return_if_fail (g_type_check_instance_is_fundamental (object, G_TYPE_OBJECT));
with, roughly:

gboolean
g_type_check_instance_is_fundamental (GTypeInstance *instance,
                                      GType          ftype)
{
  TypeNode *node;
  if (!instance || !instance->g_class)
    return FALSE;
  node = lookup_type_node_I (instance->g_class->g_type);
  return node && node->is_instantiatable && NODE_FUNDAMENTAL_TYPE (node) == ftype;
}

which isn't radically faster than g_type_check_instance_is_a() for the
non-interface case, which only adds:

  TypeNode *iface_node = lookup_type_node_I (ftype);
  if (iface_node->n_supers <= node->n_supers &&
      node->supers[node->n_supers - iface_node->n_supers] == NODE_TYPE (iface_node))
    return TRUE;

for the curious, the macros used above and lookup_type_node_I() aren't very
complex either:

#define NODE_TYPE(node)                         (node->supers[0])
#define NODE_FUNDAMENTAL_TYPE(node)             (node->supers[node->n_supers])
static inline TypeNode*
lookup_type_node_I (register GType utype)
{
  if (utype > G_TYPE_FUNDAMENTAL_MAX)
    return (TypeNode*) (utype & ~TYPE_ID_MASK);
  else
    return static_fundamental_type_nodes[utype >> G_TYPE_FUNDAMENTAL_SHIFT];
}

so i guess you might be able to save maybe 10% or 15% of
g_type_check_instance_is_a() call time, only for the G_TYPE_OBJECT
case though.

> Or maybe we should just totally dump the typecheck?

in general, or just for g_object_(un)ref()?
exactly because ref/unref are called so frequently, they are likely
to catch broken objects, which is why i wouldn't advocate removing
them from these two functions.

>   * *********************************************************
>   *  Function:                      g_type_check_instance_cast
>   *  Called:                           915215 times
>   *  Function time:                 120808380 cycles ( 2.23% of .root.)
>   *  Function+descendants time:     303024736 cycles ( 5.61% of .root.)
>   *  Distribution to Callers:
>   *     20905 times ( 2.28% of f+d time) gdk_event_translate
>   *     38552 times ( 4.20% of f+d time) pango_fontset_simple_get_font
>   *     93995 times (10.24% of f+d time) gtk_widget_event_internal
>   *     62804 times ( 6.98% of f+d time) gtk_signal_emit
>   * *********************************************************
>
> These are small fish compared to the ref/unrefs, but they still stick out
> a bit to much.

eek. this is a different profile run, and *where* do ref/unref show up
here?

---
ciaoTJ




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