mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-12-26 15:36:14 +01:00
Merge branch 'gstring-optimizations' into 'main'
Some GString optimizations See merge request GNOME/glib!3199
This commit is contained in:
commit
26728b4ecc
@ -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*
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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");
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user