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, ¶meters, &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, ¶meters, 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;