From d5d69b94754e63af275e35fc7df48732824dff81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Wed, 9 Jan 2008 16:36:34 +0000 Subject: [PATCH] gst/: Yet another gratuitous GString micro-optimisation: add a (private) function that serialises a structure appendi... Original commit message from CVS: * gst/gst_private.h: (STRUCTURE_ESTIMATED_STRING_LEN): * gst/gstcaps.c: (gst_caps_to_string): * gst/gststructure.c: (GST_ASCII_IS_STRING), (priv_gst_structure_append_to_gstring), (gst_structure_to_string): Yet another gratuitous GString micro-optimisation: add a (private) function that serialises a structure appending to an existing GString, so that when we serialise caps we don't need to alloc+free a throwaway GString for each structure (each of which also entailing multiple reallocs on the way); also use g_string_sized_new() in various places with an approximate string length to avoid reallocs within GString. See #500143. --- ChangeLog | 14 +++++++++++ gst/gst_private.h | 8 +++++++ gst/gstcaps.c | 16 +++++++------ gst/gststructure.c | 58 +++++++++++++++++++++++++++++----------------- 4 files changed, 68 insertions(+), 28 deletions(-) diff --git a/ChangeLog b/ChangeLog index 8f186d44cd..6b6ca5867e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2008-01-09 Tim-Philipp Müller + + * gst/gst_private.h: (STRUCTURE_ESTIMATED_STRING_LEN): + * gst/gstcaps.c: (gst_caps_to_string): + * gst/gststructure.c: (GST_ASCII_IS_STRING), + (priv_gst_structure_append_to_gstring), (gst_structure_to_string): + Yet another gratuitous GString micro-optimisation: add a (private) + function that serialises a structure appending to an existing + GString, so that when we serialise caps we don't need to alloc+free + a throwaway GString for each structure (each of which also entailing + multiple reallocs on the way); also use g_string_sized_new() in + various places with an approximate string length to avoid reallocs + within GString. See #500143. + 2008-01-09 Tim-Philipp Müller * gst/gststructure.c: (gst_structure_id_set_value): diff --git a/gst/gst_private.h b/gst/gst_private.h index 0e83253950..2faf3e3b05 100644 --- a/gst/gst_private.h +++ b/gst/gst_private.h @@ -39,6 +39,7 @@ extern const char g_log_domain_gstreamer[]; /* Needed for GstRegistry * */ #include "gstregistry.h" +#include "gststructure.h" G_BEGIN_DECLS @@ -65,6 +66,13 @@ void _gst_value_initialize (void); gboolean _priv_gst_registry_remove_cache_plugins (GstRegistry *registry); void _priv_gst_registry_cleanup (void); +/* used in both gststructure.c and gstcaps.c; numbers are completely made up */ +#define STRUCTURE_ESTIMATED_STRING_LEN(s) (16 + (s)->fields->len * 22) + +gboolean priv_gst_structure_append_to_gstring (const GstStructure * structure, + GString * s); + + /*** debugging categories *****************************************************/ #ifndef GST_DISABLE_GST_DEBUG diff --git a/gst/gstcaps.c b/gst/gstcaps.c index ac3545dcd6..fd330f51dc 100644 --- a/gst/gstcaps.c +++ b/gst/gstcaps.c @@ -1773,7 +1773,7 @@ gst_caps_replace (GstCaps ** caps, GstCaps * newcaps) gchar * gst_caps_to_string (const GstCaps * caps) { - guint i; + guint i, slen; GString *s; /* NOTE: This function is potentially called by the debug system, @@ -1792,10 +1792,15 @@ gst_caps_to_string (const GstCaps * caps) return g_strdup ("EMPTY"); } - s = g_string_new (""); + /* estimate a rough string length to avoid unnecessary reallocs in GString */ + slen = 0; + for (i = 0; i < caps->structs->len; i++) { + slen += STRUCTURE_ESTIMATED_STRING_LEN (gst_caps_get_structure (caps, i)); + } + + s = g_string_sized_new (slen); for (i = 0; i < caps->structs->len; i++) { GstStructure *structure; - char *sstr; if (i > 0) { /* ';' is now added by gst_structure_to_string */ @@ -1803,15 +1808,12 @@ gst_caps_to_string (const GstCaps * caps) } structure = gst_caps_get_structure (caps, i); - sstr = gst_structure_to_string (structure); - g_string_append (s, sstr); - g_free (sstr); + priv_gst_structure_append_to_gstring (structure, s); } if (s->len && s->str[s->len - 1] == ';') { /* remove latest ';' */ s->str[--s->len] = '\0'; } - return g_string_free (s, FALSE); } diff --git a/gst/gststructure.c b/gst/gststructure.c index 89f61cc3ba..c72358508a 100644 --- a/gst/gststructure.c +++ b/gst/gststructure.c @@ -1506,6 +1506,39 @@ gst_structure_value_get_generic_type (GValue * val) ((c) == '-') || ((c) == '+') || ((c) == '/') || ((c) == ':') || \ ((c) == '.')) +gboolean +priv_gst_structure_append_to_gstring (const GstStructure * structure, + GString * s) +{ + GstStructureField *field; + guint i; + + g_return_val_if_fail (s != NULL, FALSE); + + g_string_append (s, g_quark_to_string (structure->name)); + for (i = 0; i < structure->fields->len; i++) { + char *t; + GType type; + + field = GST_STRUCTURE_FIELD (structure, i); + + t = gst_value_serialize (&field->value); + type = gst_structure_value_get_generic_type (&field->value); + + g_string_append_len (s, ", ", 2); + /* FIXME: do we need to escape fieldnames? */ + g_string_append (s, g_quark_to_string (field->name)); + g_string_append_len (s, "=(", 2); + g_string_append (s, gst_structure_to_abbr (type)); + g_string_append_c (s, ')'); + g_string_append (s, GST_STR_NULL (t)); + g_free (t); + } + + g_string_append_c (s, ';'); + return TRUE; +} + /** * gst_structure_to_string: * @structure: a #GstStructure @@ -1518,9 +1551,7 @@ gst_structure_value_get_generic_type (GValue * val) gchar * gst_structure_to_string (const GstStructure * structure) { - GstStructureField *field; GString *s; - guint i; /* NOTE: This function is potentially called by the debug system, * so any calls to gst_log() (and GST_DEBUG(), GST_LOG(), etc.) @@ -1530,25 +1561,10 @@ gst_structure_to_string (const GstStructure * structure) g_return_val_if_fail (structure != NULL, NULL); - s = g_string_new (""); - g_string_append_printf (s, "%s", g_quark_to_string (structure->name)); - for (i = 0; i < structure->fields->len; i++) { - char *t; - GType type; - - field = GST_STRUCTURE_FIELD (structure, i); - - t = gst_value_serialize (&field->value); - type = gst_structure_value_get_generic_type (&field->value); - - /* FIXME: do we need to escape fieldnames? */ - g_string_append_printf (s, ", %s=(%s)%s", g_quark_to_string (field->name), - gst_structure_to_abbr (type), GST_STR_NULL (t)); - g_free (t); - } - - g_string_append_c (s, ';'); - + /* we estimate a minimum size based on the number of fields in order to + * avoid unnecessary reallocs within GString */ + s = g_string_sized_new (STRUCTURE_ESTIMATED_STRING_LEN (structure)); + priv_gst_structure_append_to_gstring (structure, s); return g_string_free (s, FALSE); }