Use pre-split element classes and pseudo-classes to optimize matching

In my testing this cuts the longest time to dispatch(), when showing the
calendar menu for the first time, from 604 to 442 milliseconds,
while reducing additional_selector_matches_style() from 32% to 13% of
CPU time used.

Bug: https://bugzilla.gnome.org/show_bug.cgi?id=687465
Reviewed-by: Jasper St. Pierre <jstpierre@mecheye.net>
This commit is contained in:
Simon McVittie 2012-11-08 15:41:31 +00:00
parent c4f6619fbd
commit 5ae2f87ce9

View File

@ -448,28 +448,20 @@ st_theme_new (const char *application_stylesheet,
static gboolean static gboolean
string_in_list (GString *stryng, string_in_list (GString *stryng,
const char *list) GStrv list)
{ {
char *cur; gchar **it;
char *l = g_strdup (list);
char *temp;
gboolean found = FALSE;
cur = strtok_r (l, " \t\f\r\n", &temp); if (list == NULL)
while (cur != NULL) return FALSE;
for (it = list; *it != NULL; it++)
{ {
if (!strqcmp (cur, stryng->str, stryng->len)) if (!strqcmp (*it, stryng->str, stryng->len))
{ return TRUE;
found = TRUE;
goto out;
}
cur = strtok_r (NULL, " \t\f\r\n", &temp);
} }
out: return FALSE;
g_free (l);
return found;
} }
static gboolean static gboolean
@ -477,7 +469,7 @@ pseudo_class_add_sel_matches_style (StTheme *a_this,
CRAdditionalSel *a_add_sel, CRAdditionalSel *a_add_sel,
StThemeNode *a_node) StThemeNode *a_node)
{ {
const char *node_pseudo_class; GStrv node_pseudo_classes;
g_return_val_if_fail (a_this g_return_val_if_fail (a_this
&& a_add_sel && a_add_sel
@ -487,12 +479,10 @@ pseudo_class_add_sel_matches_style (StTheme *a_this,
&& a_add_sel->content.pseudo->name->stryng->str && a_add_sel->content.pseudo->name->stryng->str
&& a_node, FALSE); && a_node, FALSE);
node_pseudo_class = st_theme_node_get_pseudo_class (a_node); node_pseudo_classes = st_theme_node_get_pseudo_classes (a_node);
if (node_pseudo_class == NULL) return string_in_list (a_add_sel->content.pseudo->name->stryng,
return FALSE; node_pseudo_classes);
return string_in_list (a_add_sel->content.pseudo->name->stryng, node_pseudo_class);
} }
/** /**
@ -507,7 +497,7 @@ static gboolean
class_add_sel_matches_style (CRAdditionalSel *a_add_sel, class_add_sel_matches_style (CRAdditionalSel *a_add_sel,
StThemeNode *a_node) StThemeNode *a_node)
{ {
const char *element_class; GStrv element_classes;
g_return_val_if_fail (a_add_sel g_return_val_if_fail (a_add_sel
&& a_add_sel->type == CLASS_ADD_SELECTOR && a_add_sel->type == CLASS_ADD_SELECTOR
@ -516,11 +506,10 @@ class_add_sel_matches_style (CRAdditionalSel *a_add_sel,
&& a_add_sel->content.class_name->stryng->str && a_add_sel->content.class_name->stryng->str
&& a_node, FALSE); && a_node, FALSE);
element_class = st_theme_node_get_element_class (a_node); element_classes = st_theme_node_get_element_classes (a_node);
if (element_class == NULL)
return FALSE;
return string_in_list (a_add_sel->content.class_name->stryng, element_class); return string_in_list (a_add_sel->content.class_name->stryng,
element_classes);
} }
/* /*