Improve performance: Use ->priv instead GET_PRIV() macros

Sure you already know this, but if someone don’t:

Maybe some of you have this in your *.c GObject files:

#define GET_PRIV(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), MY_TYPE_OBJECT, MyObjectPriv))

And then you use this macro in all your functions to access the GObject private structure.

You shouldn’t do this.

Instead, declare a *priv member in public structure and then access private members with my_object->priv->var

Maybe you think the performance improvement is not a lot. Well, I applied a similar patch to giggle [1] and now the startup time is ~10 second faster when opening the evolution git repository.

So, I think it’s worth ;)

Update: From Edward Hervey comments: Some of the benefits of use of G_TYPE_INSTANCE_GET_PRIVATE(): memory space gets allocated alongside your instance, avoids an extra alloc, memory is contiguous, …

[1] http://git.gnome.org/browse/giggle/commit/?id=72dbad7a4b0db2bed612d8666a640ae66082f936

Tags: ,

9 Responses to “Improve performance: Use ->priv instead GET_PRIV() macros”

  1. Alberto Ruiz says:

    Maybe the solution is to change the macro instead of having totally custom code to access the private struct all over the place?

  2. jjardon says:

    @Alberto

    IMHO, I think is simpler to have:

    MyObjectPriv *priv = my_object->priv;

    in the begining of your functions.

    Note that you still need to use G_TYPE_INSTANCE_GET_PRIVATE() in your my_object_init() function

  3. nick says:

    Thanks, this was useful. BTW very roughly how many macro calls did you have to make to get a 10s slowdown?

  4. A. Walton says:

    jjardon:

    It’s even easier to just do object->priv->field. It looks a bit uglier though.

  5. Ten seconds? Wow. Did you make sure you had a hot cache though for both cases? If you tested “run old app, make change, run patched app”, then the second time lots of the git repository will be in the page cache, so the timings are going to be unfair.

    And ten seconds out of how much total time?

  6. jjardon says:

    @Colin:
    I’ve already done, but I tested again in this order: patched app, old app and here the numbers:

    patched: ~31s
    old app: ~40s

    Yes, impressive

  7. Edward Hervey says:

    @Colin: on average calling G_TYPE_INSTANCE_GET_PRIVATE takes about 100 instruction cycles on an amd phenom with glib compiled with G_DISABLE_CAST_CHECKS…. that’s about 100 times more than what’s needed :) Put that in functions called tens of thousands of times and you’re saving millions of cycles.

    Javier, damn, you beat me again at spreading the good word :)

    Might be worth putting an update in your post explaining *why* it’s a good thing to use the instance private in the first place (memory space gets allocated alongside your instance, avoids an extra alloc, memory is contiguous, …).

    Now, here’s hoping tinymail/modest developers read this blogpost :)

  8. jjardon says:

    @Edward:

    Sure, but maybe is better to update the GObject documentation too. I’ve already fix the g_type_class_add_private() documentation example [1].

    Could you provide a patch / bug report with that info? ;)

    [1] http://git.gnome.org/browse/glib/commit/?id=0f51e995658a50dbecb74b006f05a1ea69f43558

  9. Juanjo Marin says:

    Eres un máquina !!!!