From bd0f462729cdb484e1a65b128309e9eb0d90b4c8 Mon Sep 17 00:00:00 2001 From: Christian Hergert Date: Mon, 23 Sep 2024 11:20:55 -0700 Subject: [PATCH] glib/gvariant: avoid g_renew() for definite tuples If you have a definite-tuple type such as (iiii) then the number of children that are allocated will match the offset when a GVariantBuilder has completed. That means we can avoid an expensive call into the allocator which is normally done to shrink memory use by releasing it back to the allocator. This saves about 5% of wallclock time when building such variants in a tight loop. --- glib/gvariant.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/glib/gvariant.c b/glib/gvariant.c index 8ea52d50a..5256397f6 100644 --- a/glib/gvariant.c +++ b/glib/gvariant.c @@ -3746,6 +3746,7 @@ g_variant_builder_end (GVariantBuilder *builder) { GVariantType *my_type; GVariant *value; + GVariant **children; return_val_if_invalid_builder (builder, NULL); g_return_val_if_fail (GVSB(builder)->offset >= GVSB(builder)->min_items, @@ -3774,10 +3775,14 @@ g_variant_builder_end (GVariantBuilder *builder) else g_assert_not_reached (); + children = GVSB(builder)->children; + + /* shrink allocation to release extra space to allocator */ + if G_UNLIKELY (GVSB(builder)->offset < GVSB(builder)->allocated_children) + children = g_renew (GVariant *, children, GVSB(builder)->offset); + value = g_variant_new_from_children (my_type, - g_renew (GVariant *, - GVSB(builder)->children, - GVSB(builder)->offset), + children, GVSB(builder)->offset, GVSB(builder)->trusted); GVSB(builder)->children = NULL;