Dump lookup statistics

Print out numbers of lookups, their size, and
the amount of sharing.

For widget-factory, the numbers are like this:
319 different lookups, 890 total, 18.5022 avg length

For the gtk-demo listbox example, the number are:
58 different lookups, 9742 total, 15.9997 avg length
This commit is contained in:
Matthias Clasen
2020-02-11 18:55:17 -05:00
parent 21a4fd1a5f
commit de0c61754e
3 changed files with 132 additions and 0 deletions

View File

@@ -66,6 +66,92 @@ gtk_css_lookup_value_unref (GtkCssLookupValue *value)
gtk_css_lookup_value_free (value);
}
static GHashTable *lookups;
static gboolean
gtk_css_lookup_equal (gconstpointer p1,
gconstpointer p2)
{
const GtkCssLookup *l1 = p1;
const GtkCssLookup *l2 = p2;
int i;
if (!_gtk_bitmask_equals (l1->set_values, l2->set_values))
return FALSE;
if (l1->values == NULL && l2->values == NULL)
return TRUE;
if (l1->values == NULL || l2->values == NULL)
return FALSE;
if (l1->values->len != l2->values->len)
return FALSE;
for (i = 0; i < l1->values->len; i++)
{
GtkCssLookupValue *v1 = g_ptr_array_index (l1->values, i);
GtkCssLookupValue *v2 = g_ptr_array_index (l2->values, i);
if (!_gtk_css_value_equal (v1->value, v2->value))
return FALSE;
}
return TRUE;
}
static guint
gtk_css_lookup_hash (gconstpointer data)
{
const GtkCssLookup *l = data;
int i;
guint h;
if (l->values == NULL)
return 0;
h = 0;
for (i = 0; i < l->values->len; i++)
{
GtkCssLookupValue *v = g_ptr_array_index (l->values, i);
char *s = _gtk_css_value_to_string (v->value);
h += g_str_hash (s);
g_free (s);
}
return h;
}
static gboolean
dump_lookups (gpointer data)
{
GHashTableIter iter;
GtkCssLookup *key;
gpointer value;
int total = 0;
int length = 0;
g_hash_table_iter_init (&iter, lookups);
while (g_hash_table_iter_next (&iter, (gpointer *)&key, (gpointer *)&value))
{
total += GPOINTER_TO_INT (value);
length += GPOINTER_TO_INT (value) * key->values->len;
}
g_print ("lookup stats:\n");
g_print ("\t%d different lookups, %d total, %g avg length\n",
g_hash_table_size (lookups),
total,
length / (1.0 * total));
g_hash_table_iter_init (&iter, lookups);
while (g_hash_table_iter_next (&iter, (gpointer *)&key, (gpointer *)&value))
g_print ("\t%d\t%d\n", GPOINTER_TO_INT (value), key->values->len);
g_print ("\n");
return G_SOURCE_CONTINUE;
}
GtkCssLookup *
gtk_css_lookup_new (void)
{
@@ -74,12 +160,50 @@ gtk_css_lookup_new (void)
lookup->ref_count = 1;
lookup->set_values = _gtk_bitmask_new ();
if (!lookups)
{
lookups = g_hash_table_new (gtk_css_lookup_hash, gtk_css_lookup_equal);
g_timeout_add (1000, dump_lookups, NULL);
}
return lookup;
}
void
gtk_css_lookup_register (GtkCssLookup *lookup)
{
gint count;
count = GPOINTER_TO_INT (g_hash_table_lookup (lookups, lookup));
count++;
if (count == 1)
gtk_css_lookup_ref (lookup);
g_hash_table_insert (lookups, lookup, GINT_TO_POINTER (count));
}
static void
gtk_css_lookup_unregister (GtkCssLookup *lookup)
{
gint count;
count = GPOINTER_TO_INT (g_hash_table_lookup (lookups, lookup));
g_assert (count > 0);
if (count == 1)
g_hash_table_remove (lookups, lookup);
else
{
count--;
g_hash_table_insert (lookups, lookup, GINT_TO_POINTER (count));
}
}
static void
gtk_css_lookup_free (GtkCssLookup *lookup)
{
gtk_css_lookup_unregister (lookup);
_gtk_bitmask_free (lookup->set_values);
if (lookup->values)
g_ptr_array_unref (lookup->values);
@@ -105,6 +229,10 @@ gtk_css_lookup_unref (GtkCssLookup *lookup)
lookup->ref_count--;
if (lookup->ref_count == 1 &&
GPOINTER_TO_INT (g_hash_table_lookup (lookups, lookup)) == 1)
lookup->ref_count--;
if (lookup->ref_count == 0)
gtk_css_lookup_free (lookup);
}

View File

@@ -85,6 +85,8 @@ gtk_css_lookup_get (GtkCssLookup *lookup,
return NULL;
}
void gtk_css_lookup_register (GtkCssLookup *lookup);
G_END_DECLS
#endif /* __GTK_CSS_LOOKUP_PRIVATE_H__ */

View File

@@ -996,6 +996,8 @@ gtk_css_static_style_new_compute (GtkStyleProvider *provider,
lookup,
change == 0 ? &change : NULL);
gtk_css_lookup_register (lookup);
if (_gtk_bitmask_is_empty (gtk_css_lookup_get_set_values (lookup)))
{
gtk_css_lookup_unref (lookup);