Compare commits

...

3 Commits

Author SHA1 Message Date
Matthias Clasen
c96495966e match_all: Only allocate an array when needed
My statistics show that more than half of all calls end up
with 0 matches, so we can avoid some overhead by not allocating
an array at all in this case.
2015-09-09 11:11:11 -04:00
Matthias Clasen
c4ccdd18c8 Handle match_all returning NULL
This is in preparation for not allocating an array at all if there
are no matches.
2015-09-09 11:11:03 -04:00
Matthias Clasen
e506341451 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.
2015-09-09 11:10:58 -04:00
2 changed files with 93 additions and 93 deletions

View File

@@ -1638,6 +1638,8 @@ verify_tree_get_change_results (GtkCssProvider *provider,
int i;
tree_rules = _gtk_css_selector_tree_match_all (provider->priv->tree, matcher);
if (tree_rules)
{
verify_tree_match_results (provider, matcher, tree_rules);
for (i = tree_rules->len - 1; i >= 0; i--)
@@ -1649,6 +1651,9 @@ verify_tree_get_change_results (GtkCssProvider *provider,
verify_change |= _gtk_css_selector_get_change (ruleset->selector);
}
g_ptr_array_free (tree_rules, TRUE);
}
if (change != verify_change)
{
GString *s;
@@ -1671,8 +1676,6 @@ verify_tree_get_change_results (GtkCssProvider *provider,
g_warning (s->str);
g_string_free (s, TRUE);
}
g_ptr_array_free (tree_rules, TRUE);
}
#endif
}
@@ -1711,6 +1714,8 @@ gtk_css_provider_get_style_property (GtkStyleProvider *provider,
}
tree_rules = _gtk_css_selector_tree_match_all (priv->tree, &matcher);
if (tree_rules)
{
verify_tree_match_results (css_provider, &matcher, tree_rules);
prop_name = g_strdup_printf ("-%s-%s",
@@ -1735,12 +1740,8 @@ gtk_css_provider_get_style_property (GtkStyleProvider *provider,
val->section,
val->section != NULL ? gtk_css_section_get_file (val->section) : NULL,
val->value);
found = _gtk_css_style_funcs_parse_value (value,
scanner->parser);
found = _gtk_css_style_funcs_parse_value (value, scanner->parser);
gtk_css_scanner_destroy (scanner);
break;
}
}
@@ -1751,6 +1752,8 @@ gtk_css_provider_get_style_property (GtkStyleProvider *provider,
g_free (prop_name);
g_ptr_array_free (tree_rules, TRUE);
}
gtk_widget_path_unref (path);
return found;
@@ -1797,6 +1800,8 @@ gtk_css_style_provider_lookup (GtkStyleProviderPrivate *provider,
priv = css_provider->priv;
tree_rules = _gtk_css_selector_tree_match_all (priv->tree, matcher);
if (tree_rules)
{
verify_tree_match_results (css_provider, matcher, tree_rules);
for (i = tree_rules->len - 1; i >= 0; i--)
@@ -1829,6 +1834,7 @@ gtk_css_style_provider_lookup (GtkStyleProviderPrivate *provider,
}
g_ptr_array_free (tree_rules, TRUE);
}
if (change)
{

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;
@@ -150,8 +168,11 @@ gtk_css_selector_tree_found_match (const GtkCssSelectorTree *tree,
matches = gtk_css_selector_tree_get_matches (tree);
if (matches)
{
if (!*array)
*array = g_ptr_array_sized_new (16);
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 +1735,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 +1760,13 @@ GPtrArray *
_gtk_css_selector_tree_match_all (const GtkCssSelectorTree *tree,
const GtkCssMatcher *matcher)
{
GHashTable *res;
GPtrArray *array;
GHashTableIter iter;
gpointer key;
GPtrArray *array = NULL;
update_type_references ();
res = g_hash_table_new (g_direct_hash, g_direct_equal);
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;
}