Optimize gtk_css_selector_match_all

We are dealing with really short lists here.
95% are < 10 matches, and the longest I've been able to record was 19.
So just do away with the hash table and do sorted insertion in
the array directly.
This commit is contained in:
Matthias Clasen 2015-09-09 10:46:48 -04:00
parent dbf85cc4db
commit 117b50f8fb

View File

@ -140,9 +140,27 @@ gtk_css_selector_tree_get_matches (const GtkCssSelectorTree *tree)
return (gpointer *) ((guint8 *)tree + tree->matches_offset);
}
static void
g_ptr_array_insert_sorted (GPtrArray *array,
gpointer data)
{
gint i;
for (i = 0; i < array->len; i++)
{
if (data == array->pdata[i])
return;
if (data < array->pdata[i])
break;
}
g_ptr_array_insert (array, i, data);
}
static void
gtk_css_selector_tree_found_match (const GtkCssSelectorTree *tree,
GHashTable *res)
GPtrArray *array)
{
int i;
gpointer *matches;
@ -151,7 +169,7 @@ gtk_css_selector_tree_found_match (const GtkCssSelectorTree *tree,
if (matches)
{
for (i = 0; matches[i] != NULL; i++)
g_hash_table_insert (res, matches[i], matches[i]);
g_ptr_array_insert_sorted (array, matches[i]);
}
}
@ -1714,18 +1732,6 @@ gtk_css_selectors_skip_initial_selector (GtkCssSelector *selector, const GtkCssS
return (GtkCssSelector *)gtk_css_selector_previous (selector);
}
static int
direct_ptr_compare (const void *_a, const void *_b)
{
gpointer *a = (gpointer *)_a;
gpointer *b = (gpointer *)_b;
if (*a < *b)
return -1;
else if (*a == *b)
return 0;
return 1;
}
static gboolean
gtk_css_selector_tree_match_foreach (const GtkCssSelector *selector,
const GtkCssMatcher *matcher,
@ -1751,28 +1757,15 @@ GPtrArray *
_gtk_css_selector_tree_match_all (const GtkCssSelectorTree *tree,
const GtkCssMatcher *matcher)
{
GHashTable *res;
GPtrArray *array;
GHashTableIter iter;
gpointer key;
update_type_references ();
res = g_hash_table_new (g_direct_hash, g_direct_equal);
array = g_ptr_array_sized_new (16);
for (; tree != NULL;
tree = gtk_css_selector_tree_get_sibling (tree))
gtk_css_selector_foreach (&tree->selector, matcher, gtk_css_selector_tree_match_foreach, res);
array = g_ptr_array_sized_new (g_hash_table_size (res));
g_hash_table_iter_init (&iter, res);
while (g_hash_table_iter_next (&iter, &key, NULL))
g_ptr_array_add (array, key);
g_hash_table_destroy (res);
qsort (array->pdata, array->len, sizeof (gpointer), direct_ptr_compare);
gtk_css_selector_foreach (&tree->selector, matcher, gtk_css_selector_tree_match_foreach, array);
return array;
}