GVariant singletons



Hi all,

In Unity, at least, we're pushing around quite a lot of GVariants, and while it's not slow, I was wondering if we could make even faster. If nothing, it would be a fun exercise :-)

The basic idea I have is stolen from Java's Boolean and Integer classes where they have singletons to help cut some corners in the garbage collector and comparison methods. In Java that makes a big difference. (for Integer they cache numbers up to 128 I believe)

I made a very simple benchmark to test something similar with GVariants, which I have attached to this mail. Simulating that the TRUE GVariant is a singleton I get numbers ala:

$ ./gvariant-singletons
CREATE 1000  : 0.000781s
DESTROY 1000 : 0.000430s
CREATE 1000  : 0.000042s (sngltn)
DESTROY 1000 : 0.000039s (sngltn)

Running the test numerous times I see speedups in the range of 5-20 times. Not mighty surprising - just verifies that ref() is faster than new allocations, but still good to see it in raw numbers.

One could do something similar for low valued integers - I am mostly thinking those that would be in the range of your average enum.

So I think this looks pretty interesting, and I'll probably look into it over the next days; but any comments (or showstoppers?!) are most welcome.

And yes, yes, I know this is another slap in the face for the valgrind camp. Sorry!

Cheers,
Mikkel
/* gcc gvariant-singletons.c -o gvariant-singletons $(pkg-config --cflags --libs glib-2.0 gobject-2.0) */

#include <glib.h>
#include <glib/gprintf.h>

#define N_VARIANTS 1000

void
main ()
{
  GVariant  *gvTRUE, *gvFALSE;
  GTimer    *timer;
  GVariant **variants;
  int        i;
  
  g_type_init ();
  
  variants = g_new (GVariant*, N_VARIANTS); 
  gvTRUE = g_variant_new_boolean (TRUE);
  gvFALSE = g_variant_new_boolean (FALSE);
  
  /* Dummy run */
  for (i = 0; i < N_VARIANTS; i++)
    {
      variants[i] = g_variant_new_boolean (TRUE);
      g_variant_unref (variants[i]);
    }
  
  /* NORMAL - no singletons */
  timer = g_timer_new ();
  for (i = 0; i < N_VARIANTS; i++)
    {
      variants[i] = g_variant_new_boolean (TRUE);
    }
  g_printf ("CREATE %i  : %fs\n", N_VARIANTS, g_timer_elapsed (timer, NULL));
  
  g_timer_start (timer);
  for (i = 0; i < N_VARIANTS; i++)
    {
      g_variant_unref (variants[i]);
    }
  g_printf ("DESTROY %i : %fs\n", N_VARIANTS, g_timer_elapsed (timer, NULL));
  
  /* With singleton booleans */
  g_timer_start (timer);
  for (i = 0; i < N_VARIANTS; i++)
    {
      variants[i] = g_variant_ref (gvTRUE);
    }
  g_printf ("CREATE %i  : %fs (sngltn)\n", N_VARIANTS, g_timer_elapsed (timer, NULL));
  
  g_timer_start (timer);
  for (i = 0; i < N_VARIANTS; i++)
    {
      g_variant_unref (variants[i]);
    }
  g_printf ("DESTROY %i : %fs (sngltn)\n", N_VARIANTS, g_timer_elapsed (timer, NULL));
  
  g_free (variants);
  g_variant_unref (gvTRUE);
  g_variant_unref (gvFALSE);
  
}


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