dee

Merge lp:~kamstrup/dee/optimized-getters into lp:dee

Proposed by Mikkel Kamstrup Erlandsen
Status: Merged
Approved by: Michal Hruby
Approved revision: 330
Merged at revision: 326
Proposed branch: lp:~kamstrup/dee/optimized-getters
Merge into: lp:dee
Diff against target: 392 lines (+278/-12)
2 files modified
dee/dee-sequence-model.c (+201/-9)
tests/test-benchmark.c (+77/-3)
To merge this branch: bzr merge lp:~kamstrup/dee/optimized-getters
Reviewer Review Type Date Requested Status
Michal Hruby (community) Approve
Review via email: mp+87239@code.launchpad.net

Description of the change

Optimize the getters in DeeSequenceModel by shaving off a g_variant_ref() compared to the default impl in DeeSerializableModel. Benchmarks indicate a ~13% speedup when reading strings.

This branch also adds a benchmark for reading a string column out of a seqmodel.

It is now possible to pass arguments to tests/test-benchmark that specify prefixes that the benchmark names must match in order to be run. Without args all benchmarks are run.

To post a comment you must log in.
Revision history for this message
Michal Hruby (mhr3) wrote :

The code looks clean, and I can confirm ~15% speedup in the benchmark. Rock on!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'dee/dee-sequence-model.c'
2--- dee/dee-sequence-model.c 2011-12-16 13:01:10 +0000
3+++ dee/dee-sequence-model.c 2012-01-02 10:51:24 +0000
4@@ -125,6 +125,38 @@
5 static DeeModelIter* dee_sequence_model_get_iter_at_row (DeeModel *self,
6 guint row);
7
8+static gboolean dee_sequence_model_get_bool (DeeModel *self,
9+ DeeModelIter *iter,
10+ guint column);
11+
12+static guchar dee_sequence_model_get_uchar (DeeModel *self,
13+ DeeModelIter *iter,
14+ guint column);
15+
16+static gint32 dee_sequence_model_get_int32 (DeeModel *self,
17+ DeeModelIter *iter,
18+ guint column);
19+
20+static guint32 dee_sequence_model_get_uint32 (DeeModel *self,
21+ DeeModelIter *iter,
22+ guint column);
23+
24+static gint64 dee_sequence_model_get_int64 (DeeModel *self,
25+ DeeModelIter *iter,
26+ guint column);
27+
28+static guint64 dee_sequence_model_get_uint64 (DeeModel *self,
29+ DeeModelIter *iter,
30+ guint column);
31+
32+static gdouble dee_sequence_model_get_double (DeeModel *self,
33+ DeeModelIter *iter,
34+ guint column);
35+
36+static const gchar* dee_sequence_model_get_string (DeeModel *self,
37+ DeeModelIter *iter,
38+ guint column);
39+
40 static DeeModelIter* dee_sequence_model_next (DeeModel *self,
41 DeeModelIter *iter);
42
43@@ -255,6 +287,14 @@
44 iface->get_first_iter = dee_sequence_model_get_first_iter;
45 iface->get_last_iter = dee_sequence_model_get_last_iter;
46 iface->get_iter_at_row = dee_sequence_model_get_iter_at_row;
47+ iface->get_bool = dee_sequence_model_get_bool;
48+ iface->get_uchar = dee_sequence_model_get_uchar;
49+ iface->get_int32 = dee_sequence_model_get_int32;
50+ iface->get_uint32 = dee_sequence_model_get_uint32;
51+ iface->get_int64 = dee_sequence_model_get_int64;
52+ iface->get_uint64 = dee_sequence_model_get_uint64;
53+ iface->get_double = dee_sequence_model_get_double;
54+ iface->get_string = dee_sequence_model_get_string;
55 iface->next = dee_sequence_model_next;
56 iface->prev = dee_sequence_model_prev;
57 iface->is_first = dee_sequence_model_is_first;
58@@ -484,13 +524,12 @@
59 }
60
61 static GVariant*
62-dee_sequence_model_get_value (DeeModel *self,
63- DeeModelIter *iter,
64- guint column)
65+dee_sequence_model_peek_value (DeeModel *self,
66+ DeeModelIter *iter,
67+ guint column)
68 {
69 DeeSequenceModel *_self = (DeeSequenceModel *)self;
70 GPtrArray *row;
71- GVariant *col;
72
73 g_return_val_if_fail (DEE_IS_SEQUENCE_MODEL (_self), NULL);
74 g_return_val_if_fail (iter != NULL, NULL);
75@@ -516,16 +555,25 @@
76 return NULL;
77 }
78
79- col = g_ptr_array_index (row, column);
80- if (G_UNLIKELY (col == NULL))
81+ return g_ptr_array_index (row, column);
82+}
83+
84+static GVariant*
85+dee_sequence_model_get_value (DeeModel *self,
86+ DeeModelIter *iter,
87+ guint column)
88+{
89+ GVariant *val = dee_sequence_model_peek_value (self, iter, column);
90+
91+ if (G_UNLIKELY (val == NULL))
92 {
93- g_critical ("Internal error: Column %i in DeeSequenceModel@%p"
94+ g_critical ("Unable to get value. Column %i in DeeSequenceModel@%p"
95 " holds a NULL value in row %u",
96 column, self, dee_model_get_position (self, iter));
97 return NULL;
98 }
99-
100- return g_variant_ref (col);
101+
102+ return g_variant_ref (val);
103 }
104
105 static DeeModelIter*
106@@ -559,6 +607,150 @@
107 row);
108 }
109
110+static gboolean
111+dee_sequence_model_get_bool (DeeModel *self,
112+ DeeModelIter *iter,
113+ guint column)
114+{
115+ GVariant *val = dee_sequence_model_peek_value (self, iter, column);
116+
117+ if (G_UNLIKELY (val == NULL))
118+ {
119+ g_critical ("Unable to get boolean. Column %i in DeeSequenceModel@%p"
120+ " holds a NULL value in row %u",
121+ column, self, dee_model_get_position (self, iter));
122+ return FALSE;
123+ }
124+
125+ return g_variant_get_boolean (val);
126+}
127+
128+static guchar
129+dee_sequence_model_get_uchar (DeeModel *self,
130+ DeeModelIter *iter,
131+ guint column)
132+{
133+ GVariant *val = dee_sequence_model_peek_value (self, iter, column);;
134+
135+ if (G_UNLIKELY (val == NULL))
136+ {
137+ g_critical ("Unable to get byte. Column %i in DeeSequenceModel@%p"
138+ " holds a NULL value in row %u",
139+ column, self, dee_model_get_position (self, iter));
140+ return '\0';
141+ }
142+
143+ return g_variant_get_byte (val);
144+}
145+
146+static gint32
147+dee_sequence_model_get_int32 (DeeModel *self,
148+ DeeModelIter *iter,
149+ guint column)
150+{
151+ GVariant *val = dee_sequence_model_peek_value (self, iter, column);;
152+
153+ if (G_UNLIKELY (val == NULL))
154+ {
155+ g_critical ("Unable to get int32. Column %i in DeeSequenceModel@%p"
156+ " holds a NULL value in row %u",
157+ column, self, dee_model_get_position (self, iter));
158+ return 0;
159+ }
160+
161+ return g_variant_get_int32 (val);
162+}
163+
164+static guint32
165+dee_sequence_model_get_uint32 (DeeModel *self,
166+ DeeModelIter *iter,
167+ guint column)
168+{
169+ GVariant *val = dee_sequence_model_peek_value (self, iter, column);;
170+
171+ if (G_UNLIKELY (val == NULL))
172+ {
173+ g_critical ("Unable to get uint32. Column %i in DeeSequenceModel@%p"
174+ " holds a NULL value in row %u",
175+ column, self, dee_model_get_position (self, iter));
176+ return 0;
177+ }
178+
179+ return g_variant_get_uint32 (val);
180+}
181+
182+static gint64
183+dee_sequence_model_get_int64 (DeeModel *self,
184+ DeeModelIter *iter,
185+ guint column)
186+{
187+ GVariant *val = dee_sequence_model_peek_value (self, iter, column);;
188+
189+ if (G_UNLIKELY (val == NULL))
190+ {
191+ g_critical ("Unable to get int64. Column %i in DeeSequenceModel@%p"
192+ " holds a NULL value in row %u",
193+ column, self, dee_model_get_position (self, iter));
194+ return G_GINT64_CONSTANT (0);
195+ }
196+
197+ return g_variant_get_int64 (val);
198+}
199+
200+static guint64
201+dee_sequence_model_get_uint64 (DeeModel *self,
202+ DeeModelIter *iter,
203+ guint column)
204+{
205+ GVariant *val = dee_sequence_model_peek_value (self, iter, column);;
206+
207+ if (G_UNLIKELY (val == NULL))
208+ {
209+ g_critical ("Unable to get uint64. Column %i in DeeSequenceModel@%p"
210+ " holds a NULL value in row %u",
211+ column, self, dee_model_get_position (self, iter));
212+ return G_GUINT64_CONSTANT (0);
213+ }
214+
215+ return g_variant_get_uint64 (val);
216+}
217+
218+static gdouble
219+dee_sequence_model_get_double (DeeModel *self,
220+ DeeModelIter *iter,
221+ guint column)
222+{
223+ GVariant *val = dee_sequence_model_peek_value (self, iter, column);;
224+
225+ if (G_UNLIKELY (val == NULL))
226+ {
227+ g_critical ("Unable to get double. Column %i in DeeSequenceModel@%p"
228+ " holds a NULL value in row %u",
229+ column, self, dee_model_get_position (self, iter));
230+ return 0;
231+ }
232+
233+ return g_variant_get_double (val);
234+}
235+
236+static const gchar*
237+dee_sequence_model_get_string (DeeModel *self,
238+ DeeModelIter *iter,
239+ guint column)
240+{
241+ GVariant *val = dee_sequence_model_peek_value (self, iter, column);;
242+
243+ if (G_UNLIKELY (val == NULL))
244+ {
245+ g_critical ("Unable to get string. Column %i in DeeSequenceModel@%p"
246+ " holds a NULL value in row %u",
247+ column, self, dee_model_get_position (self, iter));
248+ return NULL;
249+ }
250+
251+ return g_variant_get_string (val, NULL);
252+}
253+
254 static DeeModelIter*
255 dee_sequence_model_next (DeeModel *self,
256 DeeModelIter *iter)
257
258=== modified file 'tests/test-benchmark.c'
259--- tests/test-benchmark.c 2011-12-15 12:38:28 +0000
260+++ tests/test-benchmark.c 2012-01-02 10:51:24 +0000
261@@ -117,14 +117,28 @@
262 }
263
264 static void
265-run_benchmarks (void)
266+run_benchmarks (gchar **prefixes)
267 {
268 GList *iter;
269+ gchar **prefix;
270
271 for (iter = benchmarks; iter; iter = iter->next)
272 {
273 Benchmark *bench = (Benchmark*) iter->data;
274- run_benchmark (bench);
275+
276+ if (prefixes == NULL)
277+ run_benchmark (bench);
278+ else
279+ {
280+ for (prefix = prefixes; *prefix; prefix++)
281+ {
282+ if (g_str_has_prefix (bench->name, *prefix))
283+ {
284+ run_benchmark (bench);
285+ return;
286+ }
287+ }
288+ }
289 }
290 }
291
292@@ -173,6 +187,26 @@
293 }
294
295 static void
296+bench_seqmodel_read_string_setup (Benchmark *bench)
297+{
298+ DeeModel *model;
299+ guint limit = 2500, i;
300+
301+ model = dee_sequence_model_new ();
302+ dee_model_set_schema (model, "s", "s", "s", "u", "b", NULL);
303+
304+ for (i = 0; i < limit; i++)
305+ {
306+ gchar *random_string = g_strdup_printf ("%"G_GINT32_FORMAT,
307+ g_test_rand_int());
308+ dee_model_prepend (model, random_string, "Hello world", "!", 42, TRUE);
309+ g_free (random_string);
310+ }
311+
312+ bench->state = model;
313+}
314+
315+static void
316 bench_model_append_run (Benchmark *bench)
317 {
318 DeeModel *model;
319@@ -211,6 +245,25 @@
320 }
321
322 static void
323+bench_model_read_string_run (Benchmark *bench)
324+{
325+ DeeModel *model;
326+ DeeModelIter *iter, *end;
327+
328+ g_assert (DEE_IS_MODEL (bench->state));
329+
330+ model = DEE_MODEL (bench->state);
331+
332+
333+ for (iter = dee_model_get_first_iter (model),
334+ end = dee_model_get_last_iter (model);
335+ iter != end; iter = dee_model_next (model, iter))
336+ {
337+ dee_model_get_string (model, iter, 0);
338+ }
339+}
340+
341+static void
342 bench_gobject_teardown (Benchmark *bench)
343 {
344 GObject *obj;
345@@ -233,6 +286,13 @@
346 100,
347 NULL };
348
349+Benchmark seqmodel_read_string = { "SequenceModel.read_string",
350+ bench_seqmodel_read_string_setup,
351+ bench_model_read_string_run,
352+ bench_gobject_teardown,
353+ 1000,
354+ NULL };
355+
356 Benchmark filtermodel_collate = { "FilterModel.collate",
357 bench_filter_model_collator_setup,
358 bench_model_prepend_run,
359@@ -247,18 +307,32 @@
360 100,
361 NULL };
362
363+/* Arguments are interpreted as prefixes that benchmark names must match
364+ * in order to be run */
365 gint
366 main (gint argc, gchar *argv[])
367 {
368 g_type_init ();
369 g_thread_init (NULL);
370 g_test_init (&argc, &argv, NULL);
371+
372+ /* Extract NULL terminated array of prefixes from arguments */
373+ int i;
374+ gchar **prefixes = g_new0 (gchar*, argc);
375+ for (i = 1; i < argc; i++)
376+ {
377+ prefixes[i-1] = argv[i];
378+ }
379
380 add_benchmark (&seqmodel_append);
381 add_benchmark (&seqmodel_prepend);
382+ add_benchmark (&seqmodel_read_string);
383 add_benchmark (&filtermodel_collate);
384 add_benchmark (&filtermodel_collate_desc);
385
386- run_benchmarks ();
387+ run_benchmarks (argc > 1 ? prefixes : NULL);
388+
389+ g_free (prefixes);
390+
391 return 0;
392 }

Subscribers

People subscribed via source and target branches