mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-11-11 11:56:16 +01:00
gmessages: Avoid strings duplication if there's nothing to format
g_print(), g_printerr() and all the g_log() functions used to always duplicating a string when printing even if there's nothing to format. This can be avoided in many cases though, so if a string has no formatting directive, we can just write it as it is without duplicating and free'ing it. From my tests the potential `strchr` overhead is minimal.
This commit is contained in:
parent
438006899e
commit
71a7603e7f
@ -521,6 +521,10 @@ static gboolean g_log_debug_enabled = FALSE; /* (atomic) */
|
|||||||
/* --- functions --- */
|
/* --- functions --- */
|
||||||
|
|
||||||
static void _g_log_abort (gboolean breakpoint);
|
static void _g_log_abort (gboolean breakpoint);
|
||||||
|
static inline const char * format_string (const char *format,
|
||||||
|
va_list args,
|
||||||
|
char **out_allocated_string)
|
||||||
|
G_GNUC_PRINTF (1, 0);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_g_log_abort (gboolean breakpoint)
|
_g_log_abort (gboolean breakpoint)
|
||||||
@ -1294,7 +1298,8 @@ g_logv (const gchar *log_domain,
|
|||||||
{
|
{
|
||||||
gboolean was_fatal = (log_level & G_LOG_FLAG_FATAL) != 0;
|
gboolean was_fatal = (log_level & G_LOG_FLAG_FATAL) != 0;
|
||||||
gboolean was_recursion = (log_level & G_LOG_FLAG_RECURSION) != 0;
|
gboolean was_recursion = (log_level & G_LOG_FLAG_RECURSION) != 0;
|
||||||
gchar buffer[1025], *msg, *msg_alloc = NULL;
|
char buffer[1025], *msg_alloc = NULL;
|
||||||
|
const char *msg;
|
||||||
gint i;
|
gint i;
|
||||||
|
|
||||||
log_level &= G_LOG_LEVEL_MASK;
|
log_level &= G_LOG_LEVEL_MASK;
|
||||||
@ -1312,7 +1317,9 @@ g_logv (const gchar *log_domain,
|
|||||||
msg = buffer;
|
msg = buffer;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
msg = msg_alloc = g_strdup_vprintf (format, args);
|
{
|
||||||
|
msg = format_string (format, args, &msg_alloc);
|
||||||
|
}
|
||||||
|
|
||||||
if (expected_messages)
|
if (expected_messages)
|
||||||
{
|
{
|
||||||
@ -1783,7 +1790,7 @@ g_log_structured (const gchar *log_domain,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
message = message_allocated = g_strdup_vprintf (format, args);
|
message = format_string (format, args, &message_allocated);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add MESSAGE, PRIORITY and GLIB_DOMAIN. */
|
/* Add MESSAGE, PRIORITY and GLIB_DOMAIN. */
|
||||||
@ -2027,7 +2034,7 @@ g_log_structured_standard (const gchar *log_domain,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fields[4].value = message_allocated = g_strdup_vprintf (message_format, args);
|
fields[4].value = format_string (message_format, args, &message_allocated);
|
||||||
}
|
}
|
||||||
|
|
||||||
va_end (args);
|
va_end (args);
|
||||||
@ -3336,6 +3343,28 @@ print_string (FILE *stream,
|
|||||||
fflush (stream);
|
fflush (stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
G_ALWAYS_INLINE static inline const char *
|
||||||
|
format_string (const char *format,
|
||||||
|
va_list args,
|
||||||
|
char **out_allocated_string)
|
||||||
|
{
|
||||||
|
#ifdef G_ENABLE_DEBUG
|
||||||
|
g_assert (out_allocated_string != NULL);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* If there is no formatting to be done, avoid an allocation */
|
||||||
|
if (strchr (format, '%') == NULL)
|
||||||
|
{
|
||||||
|
*out_allocated_string = NULL;
|
||||||
|
return format;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*out_allocated_string = g_strdup_vprintf (format, args);
|
||||||
|
return *out_allocated_string;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* g_print:
|
* g_print:
|
||||||
* @format: the message format. See the printf() documentation
|
* @format: the message format. See the printf() documentation
|
||||||
@ -3357,13 +3386,14 @@ g_print (const gchar *format,
|
|||||||
...)
|
...)
|
||||||
{
|
{
|
||||||
va_list args;
|
va_list args;
|
||||||
gchar *string;
|
const gchar *string;
|
||||||
|
gchar *free_me = NULL;
|
||||||
GPrintFunc local_glib_print_func;
|
GPrintFunc local_glib_print_func;
|
||||||
|
|
||||||
g_return_if_fail (format != NULL);
|
g_return_if_fail (format != NULL);
|
||||||
|
|
||||||
va_start (args, format);
|
va_start (args, format);
|
||||||
string = g_strdup_vprintf (format, args);
|
string = format_string (format, args, &free_me);
|
||||||
va_end (args);
|
va_end (args);
|
||||||
|
|
||||||
g_mutex_lock (&g_messages_lock);
|
g_mutex_lock (&g_messages_lock);
|
||||||
@ -3375,7 +3405,7 @@ g_print (const gchar *format,
|
|||||||
else
|
else
|
||||||
print_string (stdout, string);
|
print_string (stdout, string);
|
||||||
|
|
||||||
g_free (string);
|
g_free (free_me);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -3424,13 +3454,14 @@ g_printerr (const gchar *format,
|
|||||||
...)
|
...)
|
||||||
{
|
{
|
||||||
va_list args;
|
va_list args;
|
||||||
gchar *string;
|
const char *string;
|
||||||
|
char *free_me = NULL;
|
||||||
GPrintFunc local_glib_printerr_func;
|
GPrintFunc local_glib_printerr_func;
|
||||||
|
|
||||||
g_return_if_fail (format != NULL);
|
g_return_if_fail (format != NULL);
|
||||||
|
|
||||||
va_start (args, format);
|
va_start (args, format);
|
||||||
string = g_strdup_vprintf (format, args);
|
string = format_string (format, args, &free_me);
|
||||||
va_end (args);
|
va_end (args);
|
||||||
|
|
||||||
g_mutex_lock (&g_messages_lock);
|
g_mutex_lock (&g_messages_lock);
|
||||||
@ -3442,7 +3473,7 @@ g_printerr (const gchar *format,
|
|||||||
else
|
else
|
||||||
print_string (stderr, string);
|
print_string (stderr, string);
|
||||||
|
|
||||||
g_free (string);
|
g_free (free_me);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user