
#include <stdlib.h>

#include <glib-object.h>


static void
foo (void)
{
  /* nothing */
}

static gint
shuffle (gconstpointer a,
         gconstpointer b)
{
  return (rand () % 2) ? -1 : 1;
}

static void
bench_handlers (gint num_handlers)
{
  GObject  *object = g_object_new (G_TYPE_OBJECT, NULL);
  GTimer   *timer  = g_timer_new ();
  gulong    dummy;
  gint      before = 0;
  gint      after  = 0;
  gint      i;

  gulong    handlers[num_handlers];

  for (i = 0; i < num_handlers; i++)
    {
      GConnectFlags  flags = (rand() % 2) ? G_CONNECT_AFTER : 0;

      handlers[i] = g_signal_connect_data (object, "notify",
                                           G_CALLBACK (foo), NULL,
                                           NULL, flags);

      if (flags & G_CONNECT_AFTER)
        after++;
      else
        before++;
    }

  g_printerr ("connected %d handlers (%d before, %d after):  %g seconds\n",
              i, before, after, g_timer_elapsed (timer, &dummy));

  qsort (handlers, num_handlers, sizeof (gulong), shuffle);

  g_timer_start (timer);

  for (i = 0; i < num_handlers; i++)
    g_signal_handler_disconnect (object, handlers[i]);

  g_printerr ("disconnected %d handlers:  %g seconds\n",
              i, g_timer_elapsed (timer, &dummy));

  g_timer_destroy (timer);
  g_object_unref (object);
}

gint
main (gint    argc,
      gchar  *argv[])
{
  g_type_init ();

  bench_handlers (100);
  bench_handlers (1000);
  bench_handlers (10000);
  bench_handlers (100000);

  return EXIT_SUCCESS;
}
