summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Clasen <mclasen@redhat.com>2020-06-11 11:52:57 +0000
committerMatthias Clasen <mclasen@redhat.com>2020-06-11 11:52:57 +0000
commit7df7d6dca7a480186c11189d77d8fccf639c3894 (patch)
treee8bdbc8374d885b42fb91c31cf8298ae02c371d0
parent996e22bde90913fa89ed3fd8278fac6a24be1813 (diff)
parentfb998ff52d15d00eaba69e9d573195f08c5564fe (diff)
downloadgtk+-7df7d6dca7a480186c11189d77d8fccf639c3894.tar.gz
Merge branch 'builder-parameters-speedup-gtk-3' into 'gtk-3-24'
gtkbuilder: Eliminate array reallocations in get_parameters() See merge request GNOME/gtk!2072
-rw-r--r--gtk/gtkbuilder.c20
-rw-r--r--gtk/gtkbuilderparser.c1
-rw-r--r--gtk/gtkbuilderprivate.h1
3 files changed, 20 insertions, 2 deletions
diff --git a/gtk/gtkbuilder.c b/gtk/gtkbuilder.c
index d525d952c3..93be663fa5 100644
--- a/gtk/gtkbuilder.c
+++ b/gtk/gtkbuilder.c
@@ -458,6 +458,7 @@ gtk_builder_get_parameters (GtkBuilder *builder,
GType object_type,
const gchar *object_name,
GSList *properties,
+ gsize n_properties,
GParamFlags filter_flags,
GArray **parameters,
GArray **filtered_parameters)
@@ -466,10 +467,23 @@ gtk_builder_get_parameters (GtkBuilder *builder,
DelayedProperty *property;
GError *error = NULL;
+ /* Create the two arrays with size @n_properties. The total number of elements
+ * between them will eventually be @n_properties, but it’s more important to
+ * avoid realloc()/memcpy() calls on these arrays than to be tight with memory
+ * allocations (and overallocating by 100% is no worse than what #GArray does
+ * internally with doubling its size every time it’s full).
+ *
+ * @n_properties is typically ≤ 8, so it’s
+ * (a) not much of an impact to overallocate
+ * (b) disproportionally subject to realloc()/memcpy() since the array size
+ * doubles 3 times in the first 8 elements
+ *
+ * gtk_builder_get_parameters() gets called twice for every object in every
+ * #GtkBuilder file, so it’s a fairly hot path. */
if (parameters)
- *parameters = g_array_new (FALSE, FALSE, sizeof (GParameter));
+ *parameters = g_array_sized_new (FALSE, FALSE, sizeof (GParameter), n_properties);
if (filtered_parameters)
- *filtered_parameters = g_array_new (FALSE, FALSE, sizeof (GParameter));
+ *filtered_parameters = g_array_sized_new (FALSE, FALSE, sizeof (GParameter), n_properties);
for (l = properties; l; l = l->next)
{
@@ -670,6 +684,7 @@ _gtk_builder_construct (GtkBuilder *builder,
gtk_builder_get_parameters (builder, info->type,
info->id,
info->properties,
+ info->n_properties,
param_filter_flags,
&parameters,
&construct_parameters);
@@ -814,6 +829,7 @@ _gtk_builder_apply_properties (GtkBuilder *builder,
gtk_builder_get_parameters (builder, info->type,
info->id,
info->properties,
+ info->n_properties,
G_PARAM_CONSTRUCT_ONLY,
&parameters, NULL);
diff --git a/gtk/gtkbuilderparser.c b/gtk/gtkbuilderparser.c
index 121935502e..5ee5423b17 100644
--- a/gtk/gtkbuilderparser.c
+++ b/gtk/gtkbuilderparser.c
@@ -1112,6 +1112,7 @@ end_element (GMarkupParseContext *context,
}
object_info->properties = g_slist_prepend (object_info->properties, prop_info);
+ object_info->n_properties++;
}
else
g_assert_not_reached ();
diff --git a/gtk/gtkbuilderprivate.h b/gtk/gtkbuilderprivate.h
index 06b9a7aefc..28d100a872 100644
--- a/gtk/gtkbuilderprivate.h
+++ b/gtk/gtkbuilderprivate.h
@@ -36,6 +36,7 @@ typedef struct {
gchar *id;
gchar *constructor;
GSList *properties;
+ gsize n_properties;
GSList *signals;
GSList *bindings;
GObject *object;