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.
This commit is contained in:
Tim-Philipp Müller 2008-01-09 16:36:34 +00:00
parent 73808617cf
commit d5d69b9475
4 changed files with 68 additions and 28 deletions

View file

@ -1,3 +1,17 @@
2008-01-09 Tim-Philipp Müller <tim at centricular dot net>
* 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 <tim at centricular dot net>
* gst/gststructure.c: (gst_structure_id_set_value):

View file

@ -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

View file

@ -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);
}

View file

@ -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);
}