Merge branch 'gstring-optimizations' into 'main'

Some GString optimizations

See merge request GNOME/glib!3199
This commit is contained in:
Philip Withnall 2023-01-16 12:38:54 +00:00
commit 26728b4ecc
4 changed files with 108 additions and 40 deletions

View File

@ -195,13 +195,6 @@ free_list_node (GMarkupParseContext *context, GSList *node)
context->spare_list_nodes = g_slist_concat (node, context->spare_list_nodes);
}
static inline void
string_blank (GString *string)
{
string->str[0] = '\0';
string->len = 0;
}
/**
* g_markup_parse_context_new:
* @parser: a #GMarkupParser
@ -856,7 +849,7 @@ release_chunk (GMarkupParseContext *context, GString *str)
g_string_free (str, TRUE);
return;
}
string_blank (str);
g_string_truncate (str, 0);
node = get_list_node (context, str);
context->spare_chunks = g_slist_concat (node, context->spare_chunks);
}
@ -881,7 +874,7 @@ add_to_partial (GMarkupParseContext *context,
}
if (text_start != text_end)
g_string_insert_len (context->partial_chunk, -1,
g_string_append_len (context->partial_chunk,
text_start, text_end - text_start);
}
@ -889,7 +882,7 @@ static inline void
truncate_partial (GMarkupParseContext *context)
{
if (context->partial_chunk != NULL)
string_blank (context->partial_chunk);
g_string_truncate (context->partial_chunk, 0);
}
static inline const gchar*

View File

@ -75,22 +75,29 @@
*/
static void
g_string_maybe_expand (GString *string,
gsize len)
g_string_expand (GString *string,
gsize len)
{
/* Detect potential overflow */
if G_UNLIKELY ((G_MAXSIZE - string->len - 1) < len)
g_error ("adding %" G_GSIZE_FORMAT " to string would overflow", len);
if (string->len + len >= string->allocated_len)
{
string->allocated_len = g_nearest_pow (string->len + len + 1);
/* If the new size is bigger than G_MAXSIZE / 2, only allocate enough
* memory for this string and don't over-allocate. */
if (string->allocated_len == 0)
string->allocated_len = string->len + len + 1;
string->str = g_realloc (string->str, string->allocated_len);
}
string->allocated_len = g_nearest_pow (string->len + len + 1);
/* If the new size is bigger than G_MAXSIZE / 2, only allocate enough
* memory for this string and don't over-allocate.
*/
if (string->allocated_len == 0)
string->allocated_len = string->len + len + 1;
string->str = g_realloc (string->str, string->allocated_len);
}
static inline void
g_string_maybe_expand (GString *string,
gsize len)
{
if (G_UNLIKELY (string->len + len >= string->allocated_len))
g_string_expand (string, len);
}
/**
@ -113,7 +120,7 @@ g_string_sized_new (gsize dfl_size)
string->len = 0;
string->str = NULL;
g_string_maybe_expand (string, MAX (dfl_size, 64));
g_string_expand (string, MAX (dfl_size, 64));
string->str[0] = 0;
return string;
@ -351,8 +358,8 @@ g_string_assign (GString *string,
* Returns: (transfer none): @string
*/
GString *
g_string_truncate (GString *string,
gsize len)
(g_string_truncate) (GString *string,
gsize len)
{
g_return_val_if_fail (string != NULL, NULL);
@ -532,8 +539,8 @@ g_string_append_uri_escaped (GString *string,
* Returns: (transfer none): @string
*/
GString *
g_string_append (GString *string,
const gchar *val)
(g_string_append) (GString *string,
const gchar *val)
{
return g_string_insert_len (string, -1, val, -1);
}
@ -557,9 +564,9 @@ g_string_append (GString *string,
* Returns: (transfer none): @string
*/
GString *
g_string_append_len (GString *string,
const gchar *val,
gssize len)
(g_string_append_len) (GString *string,
const gchar *val,
gssize len)
{
return g_string_insert_len (string, -1, val, len);
}
@ -574,10 +581,9 @@ g_string_append_len (GString *string,
*
* Returns: (transfer none): @string
*/
#undef g_string_append_c
GString *
g_string_append_c (GString *string,
gchar c)
(g_string_append_c) (GString *string,
gchar c)
{
g_return_val_if_fail (string != NULL, NULL);

View File

@ -35,6 +35,7 @@
#include <glib/gunicode.h>
#include <glib/gbytes.h>
#include <glib/gutils.h> /* for G_CAN_INLINE */
#include <string.h>
G_BEGIN_DECLS
@ -162,13 +163,15 @@ GString* g_string_append_uri_escaped (GString *string,
const gchar *reserved_chars_allowed,
gboolean allow_utf8);
/* -- optimize g_strig_append_c --- */
#ifndef __GTK_DOC_IGNORE__
#ifdef G_CAN_INLINE
G_ALWAYS_INLINE
static inline GString*
g_string_append_c_inline (GString *gstring,
gchar c)
{
if (gstring->len + 1 < gstring->allocated_len)
if (G_LIKELY (gstring->len + 1 < gstring->allocated_len))
{
gstring->str[gstring->len++] = c;
gstring->str[gstring->len] = 0;
@ -178,8 +181,53 @@ g_string_append_c_inline (GString *gstring,
return gstring;
}
#define g_string_append_c(gstr,c) g_string_append_c_inline (gstr, c)
G_ALWAYS_INLINE
static inline GString *
g_string_append_len_inline (GString *gstring,
const char *val,
gssize len)
{
if (len < 0)
len = strlen (val);
if (G_LIKELY (gstring->len + len < gstring->allocated_len))
{
char *end = gstring->str + gstring->len;
if (G_LIKELY (val + len <= end || val > end + len))
memcpy (end, val, len);
else
memmove (end, val, len);
gstring->len += len;
gstring->str[gstring->len] = 0;
return gstring;
}
else
return g_string_insert_len (gstring, -1, val, len);
}
#define g_string_append_len(gstr,val,len) g_string_append_len_inline (gstr, val, len)
G_ALWAYS_INLINE
static inline GString *
g_string_truncate_inline (GString *gstring,
gsize len)
{
gstring->len = MIN (len, gstring->len);
gstring->str[gstring->len] = '\0';
return gstring;
}
#define g_string_truncate(gstr,len) g_string_truncate_inline (gstr, len)
#if G_GNUC_CHECK_VERSION (2, 0)
#define g_string_append(gstr,val) g_string_append_len (gstr, val, __builtin_constant_p (val) ? (gssize) strlen (val) : (gssize) -1)
#endif
#endif /* G_CAN_INLINE */
#endif /* __GTK_DOC_IGNORE__ */
GLIB_DEPRECATED
GString *g_string_down (GString *string);

View File

@ -193,8 +193,11 @@ test_string_append_c (void)
else
(g_string_append_c) (string, 'a'+(i%26));
g_assert((strlen("hi pete!") + 10000) == string->len);
g_assert((strlen("hi pete!") + 10000) == strlen(string->str));
g_assert_true ((strlen("hi pete!") + 10000) == string->len);
g_assert_true ((strlen("hi pete!") + 10000) == strlen(string->str));
for (i = 0; i < 10000; i++)
g_assert_true (string->str[strlen ("Hi pete!") + i] == 'a' + (i%26));
g_string_free (string, TRUE);
}
@ -203,17 +206,35 @@ static void
test_string_append (void)
{
GString *string;
char *tmp;
int i;
tmp = g_strdup ("more");
/* append */
string = g_string_new ("firsthalf");
g_string_append (string, "lasthalf");
g_string_append (string, "last");
(g_string_append) (string, "half");
g_assert_cmpstr (string->str, ==, "firsthalflasthalf");
i = 0;
g_string_append (string, &tmp[i++]);
(g_string_append) (string, &tmp[i++]);
g_assert_true (i == 2);
g_assert_cmpstr (string->str, ==, "firsthalflasthalfmoreore");
g_string_free (string, TRUE);
/* append_len */
string = g_string_new ("firsthalf");
g_string_append_len (string, "lasthalfjunkjunk", strlen ("lasthalf"));
g_assert_cmpstr (string->str, ==, "firsthalflasthalf");
g_string_append_len (string, "lasthalfjunkjunk", strlen ("last"));
(g_string_append_len) (string, "halfjunkjunk", strlen ("half"));
g_string_append_len (string, "more", -1);
(g_string_append_len) (string, "ore", -1);
g_assert_cmpstr (string->str, ==, "firsthalflasthalfmoreore");
g_string_free (string, TRUE);
}
@ -415,7 +436,7 @@ test_string_truncate (void)
g_assert (string->len == strlen("testing"));
g_assert_cmpstr (string->str, ==, "testing");
g_string_truncate (string, 4);
(g_string_truncate) (string, 4);
g_assert (string->len == 4);
g_assert_cmpstr (string->str, ==, "test");