Re: Fast handling of class-closure-only signals
- From: Soeren Sandmann <sandmann daimi au dk>
- To: Owen Taylor <otaylor redhat com>
- Cc: gtk-devel-list gnome org
- Subject: Re: Fast handling of class-closure-only signals
- Date: 19 Sep 2003 00:26:54 +0200
Owen Taylor <otaylor redhat com> writes:
> Do we have a profile of a micro-benchmark that just does class-closure
> only signal emissions, to see where the time is going?
I am attaching a benchmark that emits class-closure-only signals with
prototypes like GtkContainer::check_resize, GtkWidget::event, and
GtkWidget::size_allocate.
Søren
#include <glib-object.h>
#include <gtk/gtk.h>
typedef struct _BenchmarkClass BenchmarkClass;
typedef struct _Benchmark Benchmark;
enum {
EVENT,
SIZE_ALLOCATE,
CHECK_RESIZE,
LAST_SIGNAL,
};
struct _Benchmark
{
GObject parent;
};
struct _BenchmarkClass
{
GObjectClass parent;
gboolean (* event) (Benchmark *b, GdkEvent *event);
void (* size_allocate) (Benchmark *b, GtkAllocation *allocation);
void (* check_resize) (Benchmark *b);
};
static guint benchmark_signals [LAST_SIGNAL] = { 0 } ;
static void benchmark_class_init (GObjectClass *class);
static gboolean benchmark_event (Benchmark *b,
GdkEvent *e);
static void benchmark_size_allocate (Benchmark *b,
GtkAllocation *a);
static void benchmark_check_resize (Benchmark *b);
#define TYPE_BENCHMARK (benchmark_get_type())
GType
benchmark_get_type (void)
{
static GType object_type = 0;
if (!object_type)
{
static const GTypeInfo object_info = {
sizeof (BenchmarkClass),
(GBaseInitFunc) NULL,
(GBaseFinalizeFunc) NULL,
(GClassInitFunc) benchmark_class_init,
NULL, /* class_finalize */
NULL, /* class_data */
sizeof (Benchmark),
0, /* n_preallocs */
(GInstanceInitFunc) NULL,
};
object_type = g_type_register_static (G_TYPE_OBJECT,
"Benchmark",
&object_info, 0);
}
return object_type;
}
#define g_marshal_value_peek_boxed(v) g_value_get_boxed (v)
void
marshal_BOOLEAN__BOXED (GClosure *closure,
GValue *return_value,
guint n_param_values,
const GValue *param_values,
gpointer invocation_hint,
gpointer marshal_data)
{
typedef gboolean (*GMarshalFunc_BOOLEAN__BOXED) (gpointer data1,
gpointer arg_1,
gpointer data2);
register GMarshalFunc_BOOLEAN__BOXED callback;
register GCClosure *cc = (GCClosure*) closure;
register gpointer data1, data2;
gboolean v_return;
g_return_if_fail (return_value != NULL);
g_return_if_fail (n_param_values == 2);
if (G_CCLOSURE_SWAP_DATA (closure))
{
data1 = closure->data;
data2 = g_value_peek_pointer (param_values + 0);
}
else
{
data1 = g_value_peek_pointer (param_values + 0);
data2 = closure->data;
}
callback = (GMarshalFunc_BOOLEAN__BOXED) (marshal_data ? marshal_data : cc->callback);
v_return = callback (data1,
g_marshal_value_peek_boxed (param_values + 1),
data2);
g_value_set_boolean (return_value, v_return);
}
static void
benchmark_class_init (GObjectClass *class)
{
BenchmarkClass *benchmark_class = (BenchmarkClass *)class;
benchmark_signals[SIZE_ALLOCATE] =
g_signal_new ("size_allocate",
G_TYPE_FROM_CLASS (class),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (BenchmarkClass, size_allocate),
NULL, NULL,
g_cclosure_marshal_VOID__BOXED,
G_TYPE_NONE, 1,
GDK_TYPE_RECTANGLE | G_SIGNAL_TYPE_STATIC_SCOPE);
benchmark_signals[CHECK_RESIZE] =
g_signal_new ("check_resize",
G_OBJECT_CLASS_TYPE (class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (BenchmarkClass, check_resize),
NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
benchmark_signals[EVENT] =
g_signal_new ("event",
G_TYPE_FROM_CLASS (class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (BenchmarkClass, event),
_gtk_boolean_handled_accumulator, NULL,
marshal_BOOLEAN__BOXED,
G_TYPE_BOOLEAN, 1,
GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
benchmark_class->event = benchmark_event;
benchmark_class->size_allocate = benchmark_size_allocate;
benchmark_class->check_resize = benchmark_check_resize;
}
static gboolean
benchmark_event (Benchmark *b,
GdkEvent *e)
{
return FALSE;
}
static void
benchmark_size_allocate (Benchmark *b,
GtkAllocation *a)
{
return;
}
static void
benchmark_check_resize (Benchmark *b)
{
return;
}
#define N_SIGNALS 5000000
int
main ()
{
Benchmark *b;
int i;
GTimer *timer;
g_type_init ();
b = g_object_new (TYPE_BENCHMARK, NULL);
timer = g_timer_new ();
for (i = 0; i < N_SIGNALS; ++i)
{
GtkAllocation alloc = { 0, 0, 100, 100 };
g_signal_emit (b, benchmark_signals[SIZE_ALLOCATE],
0, &alloc);
}
g_print ("time to emit %d dummy \"size_allocate\" signals: %f\n",
N_SIGNALS, g_timer_elapsed (timer, NULL));
g_timer_reset (timer);
for (i = 0; i < N_SIGNALS; ++i)
{
gboolean retval;
GdkEvent event;
event.type = GDK_EXPOSE;
g_signal_emit (b, benchmark_signals[EVENT], 0, &event, &retval);
}
g_print ("time to emit %d dummy \"event\" signals: %f\n",
N_SIGNALS, g_timer_elapsed (timer, NULL));
g_timer_reset (timer);
for (i = 0; i < N_SIGNALS; ++i)
{
g_signal_emit (b, benchmark_signals[CHECK_RESIZE], 0);
}
g_print ("time to emit %d dummy \"check_resize\" signals: %f\n",
N_SIGNALS, g_timer_elapsed (timer, NULL));
for (i = 0; i < 3452345; ++i)
sleep (10);
return 0;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]