forked from AuroraMiddleware/gtk
Avoid O(n²) walking of string arrays
"Yo, we heard you like traversing NULL-terminated arrays to operate on them, so we called g_strv_length() as the for condition, so you can iterate the array while iterating the array." Instead of making famed rapper and television producer Xzibit proud, we should avoid calling g_strv_length() on an array while looping on the array, to avoid quadratic complexity. We do this in various places that deal with arrays of strings that we cannot really guess are short enough not to matter — e.g. the list of CSS selectors in the inspector, or the required authentication information for printing.
This commit is contained in:
parent
3b41daca78
commit
e259b2f30d
@ -706,24 +706,27 @@ password_dialog_response (GtkWidget *dialog,
|
|||||||
GtkPrintBackend *backend)
|
GtkPrintBackend *backend)
|
||||||
{
|
{
|
||||||
GtkPrintBackendPrivate *priv = backend->priv;
|
GtkPrintBackendPrivate *priv = backend->priv;
|
||||||
gint i;
|
gint i, auth_info_len;
|
||||||
|
|
||||||
if (response_id == GTK_RESPONSE_OK)
|
if (response_id == GTK_RESPONSE_OK)
|
||||||
gtk_print_backend_set_password (backend, priv->auth_info_required, priv->auth_info, priv->store_auth_info);
|
gtk_print_backend_set_password (backend, priv->auth_info_required, priv->auth_info, priv->store_auth_info);
|
||||||
else
|
else
|
||||||
gtk_print_backend_set_password (backend, priv->auth_info_required, NULL, FALSE);
|
gtk_print_backend_set_password (backend, priv->auth_info_required, NULL, FALSE);
|
||||||
|
|
||||||
for (i = 0; i < g_strv_length (priv->auth_info_required); i++)
|
/* We want to clear the data before freeing it */
|
||||||
|
auth_info_len = g_strv_length (priv->auth_info_required);
|
||||||
|
for (i = 0; i < auth_info_len; i++)
|
||||||
|
{
|
||||||
if (priv->auth_info[i] != NULL)
|
if (priv->auth_info[i] != NULL)
|
||||||
{
|
{
|
||||||
memset (priv->auth_info[i], 0, strlen (priv->auth_info[i]));
|
memset (priv->auth_info[i], 0, strlen (priv->auth_info[i]));
|
||||||
g_free (priv->auth_info[i]);
|
g_free (priv->auth_info[i]);
|
||||||
priv->auth_info[i] = NULL;
|
priv->auth_info[i] = NULL;
|
||||||
}
|
}
|
||||||
g_free (priv->auth_info);
|
}
|
||||||
priv->auth_info = NULL;
|
|
||||||
|
|
||||||
g_strfreev (priv->auth_info_required);
|
g_clear_pointer (&priv->auth_info, g_free);
|
||||||
|
g_clear_pointer (&priv->auth_info_required, g_strfreev);
|
||||||
|
|
||||||
gtk_widget_destroy (dialog);
|
gtk_widget_destroy (dialog);
|
||||||
|
|
||||||
|
@ -64,7 +64,7 @@ gtk_inspector_selector_set_object (GtkInspectorSelector *oh,
|
|||||||
GObject *object)
|
GObject *object)
|
||||||
{
|
{
|
||||||
GtkTreeIter iter, parent;
|
GtkTreeIter iter, parent;
|
||||||
gint i;
|
gint i, words_len;
|
||||||
GtkWidget *widget;
|
GtkWidget *widget;
|
||||||
gchar *path, **words;
|
gchar *path, **words;
|
||||||
const gchar *title;
|
const gchar *title;
|
||||||
@ -85,7 +85,8 @@ gtk_inspector_selector_set_object (GtkInspectorSelector *oh,
|
|||||||
path = gtk_widget_path_to_string (gtk_widget_get_path (widget));
|
path = gtk_widget_path_to_string (gtk_widget_get_path (widget));
|
||||||
words = g_strsplit (path, " ", 0);
|
words = g_strsplit (path, " ", 0);
|
||||||
|
|
||||||
for (i = 0; i < g_strv_length (words); i++)
|
words_len = g_strv_length (words);
|
||||||
|
for (i = 0; i < words_len; i++)
|
||||||
{
|
{
|
||||||
gtk_tree_store_append (oh->priv->model, &iter, i ? &parent : NULL);
|
gtk_tree_store_append (oh->priv->model, &iter, i ? &parent : NULL);
|
||||||
gtk_tree_store_set (oh->priv->model, &iter,
|
gtk_tree_store_set (oh->priv->model, &iter,
|
||||||
|
@ -109,7 +109,7 @@ get_secret_cb (GObject *source_object,
|
|||||||
*key = NULL,
|
*key = NULL,
|
||||||
*value = NULL;
|
*value = NULL;
|
||||||
GVariantIter *iter = NULL;
|
GVariantIter *iter = NULL;
|
||||||
guint i;
|
guint i, required_len;
|
||||||
gint pw_field = -1;
|
gint pw_field = -1;
|
||||||
|
|
||||||
task = user_data;
|
task = user_data;
|
||||||
@ -228,7 +228,8 @@ get_secret_cb (GObject *source_object,
|
|||||||
fail:
|
fail:
|
||||||
/* Error out */
|
/* Error out */
|
||||||
GTK_NOTE (PRINTING, g_print ("Failed to lookup secret.\n"));
|
GTK_NOTE (PRINTING, g_print ("Failed to lookup secret.\n"));
|
||||||
for (i = 0; i < g_strv_length (task_data->auth_info_required); i++)
|
required_len = g_strv_length (task_data->auth_info_required);
|
||||||
|
for (i = 0; i < required_len; i++)
|
||||||
{
|
{
|
||||||
/* Not all fields of auth_info are neccessarily written so we can not
|
/* Not all fields of auth_info are neccessarily written so we can not
|
||||||
use strfreev here */
|
use strfreev here */
|
||||||
|
@ -142,7 +142,7 @@ record_events (const gchar *ui_file,
|
|||||||
GError *error;
|
GError *error;
|
||||||
gchar *contents;
|
gchar *contents;
|
||||||
gchar **actions;
|
gchar **actions;
|
||||||
gint i;
|
gint i, len;
|
||||||
|
|
||||||
builder = gtk_builder_new ();
|
builder = gtk_builder_new ();
|
||||||
error = NULL;
|
error = NULL;
|
||||||
@ -153,7 +153,8 @@ record_events (const gchar *ui_file,
|
|||||||
g_assert_no_error (error);
|
g_assert_no_error (error);
|
||||||
actions = g_strsplit (contents, "\n", 0);
|
actions = g_strsplit (contents, "\n", 0);
|
||||||
|
|
||||||
for (i = 0; i < g_strv_length (actions); i++)
|
len = g_strv_length (actions);
|
||||||
|
for (i = 0; i < len; i++)
|
||||||
do_action (builder, actions[i], string);
|
do_action (builder, actions[i], string);
|
||||||
|
|
||||||
g_object_unref (builder);
|
g_object_unref (builder);
|
||||||
|
Loading…
Reference in New Issue
Block a user