]> Pileus Git - ~andy/gtk/blob - perf/README
New function; it lets us time the expose sequence of a widget.
[~andy/gtk] / perf / README
1 README for gtk+/perf
2 --------------------
3
4 This is a framework for testing performance in GTK+.   For GTK+, being
5 performant does not only mean "paint widgets fast".  It also means
6 things like the time needed to set up widgets, to map and draw a
7 window for the first time, and emitting/propagating signals.
8
9 The following is accurate as of 2005/07/28.
10
11
12 Using the framework
13 -------------------
14
15 Right now the framework is very simple; it just has utility functions
16 to time widget creation, mapping, exposure, and destruction.  To run
17 such a test, you use the GtkWidgetProfiler object in
18 gtkwidgetprofiler.h.
19
20 The gtk_widget_profiler_profile_boot() function will emit the
21 "create-widget" signal so that you can create your widget for
22 testing.  It will then take timings for the widget, and emit the
23 "report" signal as appropriate.
24
25 The "create-widget" signal:
26
27   The handler has this form:
28
29     GtkWidget *create_widget_callback (GtkWidgetProfiler *profiler, 
30                                        gpointer user_data);
31
32   You need to create a widget in your handler, and return it.  Do not
33   show the widget; the profiler will do that by itself at the right
34   time, and will actually complain if you show the widget.
35
36
37 The "report" signal:
38
39   This function will get called when the profiler wants to report that
40   it finished timing an important stage in the lifecycle of your
41   widget.  The handler has this form:
42
43     void report_callback (GtkWidgetProfiler      *profiler,
44                           GtkWidgetProfilerReport report,
45                           GtkWidget              *widget,
46                           gdouble                 elapsed,
47                           gpointer                user_data);
48
49   The "report" argument tells you what happened to your widget:
50
51     GTK_WIDGET_PROFILER_REPORT_CREATE.  A timer gets started right
52     before the profiler emits the "create-widget" signal,, and it gets
53     stopped when your callback returns with the new widget.  This
54     measures the time it takes to set up your widget, but not show it.
55
56     GTK_WIDGET_PROFILER_REPORT_MAP.  A timer gets started right before
57     the profiler calls gtk_widget_show_all() on your widget, and it
58     gets stopped when the the widget has been mapped.
59
60     GTK_WIDGET_PROFILER_REPORT_EXPOSE.  A timer gets started right before
61     the profiler starts waiting for GTK+ and the X server to finish
62     painting your widget, and it gets stopped when the widget is fully
63     painted to the screen.
64
65     GTK_WIDGET_PROFILER_REPORT_DESTROY.  A timer gets started right
66     before the profiler calls gtk_widget_destroy() on your widget, and
67     it gets stopped when gtk_widget_destroy() returns.
68
69 As a very basic example of using GtkWidgetProfiler is this:
70
71 ----------------------------------------------------------------------
72 #include <stdio.h>
73 #include <gtk/gtk.h>
74 #include "gtkwidgetprofiler.h"
75
76 static GtkWidget *
77 create_widget_cb (GtkWidgetProfiler *profiler, gpointer data)
78 {
79   GtkWidget *window;
80
81   window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
82   /* ... fill the window with widgets, and don't show them ... */
83
84   return window;
85 }
86
87 static void
88 report_cb (GtkWidgetProfiler *profiler, GtkWidgetProfilerReport report, GtkWidget *widget, gdouble elapsed, gpointer data)
89 {
90   const char *type;
91
92   switch (report) {
93   case GTK_WIDGET_PROFILER_REPORT_CREATE:
94     type = "widget creation";
95     break;
96
97   case GTK_WIDGET_PROFILER_REPORT_MAP:
98     type = "widget map";
99     break;
100
101   case GTK_WIDGET_PROFILER_REPORT_EXPOSE:
102     type = "widget expose";
103     break;
104
105   case GTK_WIDGET_PROFILER_REPORT_DESTROY:
106     type = "widget destruction";
107     break;
108
109   default:
110     g_assert_not_reached ();
111     type = NULL;
112   }
113
114   fprintf (stderr, "%s: %g sec\n", type, elapsed);
115
116   if (report == GTK_WIDGET_PROFILER_REPORT_DESTROY)
117     fputs ("\n", stderr);
118 }
119
120 int
121 main (int argc, char **argv)
122 {
123   GtkWidgetProfiler *profiler;
124
125   gtk_init (&argc, &argv);
126
127   profiler = gtk_widget_profiler_new ();
128   g_signal_connect (profiler, "create-widget",
129                     G_CALLBACK (create_widget_cb), NULL);
130   g_signal_connect (profiler, "report",
131                     G_CALLBACK (report_cb), NULL);
132
133   gtk_widget_profiler_set_num_iterations (profiler, 100);
134   gtk_widget_profiler_profile_boot (profiler);
135   
136   return 0;
137 }
138
139 ----------------------------------------------------------------------
140
141
142 Getting meaningful results
143 --------------------------
144
145 Getting times for widget creation/mapping/exposing/destruction is
146 interesting, but how do you actually find the places that need
147 optimizing?
148
149 Why, you run the tests under a profiler, of course.
150
151 FIXME: document how to do this.
152
153
154 Feedback
155 --------
156
157 Please mail your feedback to Federico Mena-Quintero <federico@novell.com>.
158 This performance framework is a work in progress.