diff options
author | Søren Sandmann Pedersen <sandmann@daimi.au.dk> | 2010-11-10 05:52:13 -0500 |
---|---|---|
committer | Søren Sandmann Pedersen <sandmann@daimi.au.dk> | 2011-06-29 02:48:22 -0400 |
commit | f5773082751d4d94965910fe2591aaeecdb06b97 (patch) | |
tree | 633b75ae9d498c55b682ff57cca53b5f51803bb7 | |
parent | 1d22fff69fb539119fcf26a31a2f9147307e0b8f (diff) |
More GtkTreeView performance hacks.
On x86-64 GLib is buggy in that g_atomic_get_pointer() ends up taking
a mutex instead of just using atomic instructions. This makes GValue
handling really slow, so avoid that by directly comparing the contents.
-rw-r--r-- | footreedatalist.c | 206 | ||||
-rw-r--r-- | sysprof.c | 2 |
2 files changed, 98 insertions, 110 deletions
diff --git a/footreedatalist.c b/footreedatalist.c index 21e4874..9f656f1 100644 --- a/footreedatalist.c +++ b/footreedatalist.c @@ -21,7 +21,9 @@ */ #include "footreedatalist.h" +#include "footreestore.h" #include <string.h> +#include <glib.h> static FooTreeDataList *cache; @@ -322,137 +324,126 @@ _foo_tree_data_list_node_copy (FooTreeDataList *list, return new_list; } +static int +fast_string_compare (const char *str1, const char *str2) +{ + return strcmp (str1, str2); +} + gint _foo_tree_data_list_compare_func (GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer user_data) { + FooTreeStore *store = (FooTreeStore *)model; gint column = GPOINTER_TO_INT (user_data); - GType type = gtk_tree_model_get_column_type (model, column); - GValue a_value = {0, }; - GValue b_value = {0, }; + GType type = store->column_headers[column]; gint retval; const gchar *stra, *strb; + FooTreeDataList *list1, *list2; - gtk_tree_model_get_value (model, a, column, &a_value); - gtk_tree_model_get_value (model, b, column, &b_value); + list1 = ((GNode *)a->user_data)->data; + list2 = ((GNode *)b->user_data)->data; - switch (get_fundamental_type (type)) + while (column-- > 0 && list1 && list2) + { + list1 = list1->next; + list2 = list2->next; + } + + switch (type) { + case G_TYPE_INT: case G_TYPE_BOOLEAN: - if (g_value_get_boolean (&a_value) < g_value_get_boolean (&b_value)) - retval = -1; - else if (g_value_get_boolean (&a_value) == g_value_get_boolean (&b_value)) - retval = 0; - else - retval = 1; + case G_TYPE_ENUM: + if (list1->data.v_int < list2->data.v_int) + retval = -1; + else if (list1->data.v_int == list2->data.v_int) + retval = 0; + else + retval = 0; break; case G_TYPE_CHAR: - if (g_value_get_char (&a_value) < g_value_get_char (&b_value)) - retval = -1; - else if (g_value_get_char (&a_value) == g_value_get_char (&b_value)) - retval = 0; - else - retval = 1; + if (list1->data.v_char < list2->data.v_char) + retval = -1; + else if (list1->data.v_char == list2->data.v_char) + retval = 0; + else + retval = 1; break; case G_TYPE_UCHAR: - if (g_value_get_uchar (&a_value) < g_value_get_uchar (&b_value)) - retval = -1; - else if (g_value_get_uchar (&a_value) == g_value_get_uchar (&b_value)) - retval = 0; - else - retval = 1; - break; - case G_TYPE_INT: - if (g_value_get_int (&a_value) < g_value_get_int (&b_value)) - retval = -1; - else if (g_value_get_int (&a_value) == g_value_get_int (&b_value)) - retval = 0; - else - retval = 1; - break; + if (list1->data.v_uchar < list2->data.v_uchar) + retval = -1; + else if (list1->data.v_uchar == list2->data.v_uchar) + retval = 0; + else + retval = 1; + break; + case G_TYPE_FLAGS: case G_TYPE_UINT: - if (g_value_get_uint (&a_value) < g_value_get_uint (&b_value)) - retval = -1; - else if (g_value_get_uint (&a_value) == g_value_get_uint (&b_value)) - retval = 0; - else - retval = 1; - break; + if (list1->data.v_uint < list2->data.v_uint) + retval = -1; + else if (list1->data.v_uint == list2->data.v_uint) + retval = 0; + else + retval = 1; + break; case G_TYPE_LONG: - if (g_value_get_long (&a_value) < g_value_get_long (&b_value)) - retval = -1; - else if (g_value_get_long (&a_value) == g_value_get_long (&b_value)) - retval = 0; - else - retval = 1; - break; + if (list1->data.v_long < list2->data.v_long) + retval = -1; + else if (list1->data.v_long == list2->data.v_long) + retval = 0; + else + retval = 1; + break; case G_TYPE_ULONG: - if (g_value_get_ulong (&a_value) < g_value_get_ulong (&b_value)) - retval = -1; - else if (g_value_get_ulong (&a_value) == g_value_get_ulong (&b_value)) - retval = 0; - else - retval = 1; - break; + if (list1->data.v_ulong < list2->data.v_ulong) + retval = -1; + else if (list1->data.v_ulong == list2->data.v_ulong) + retval = 0; + else + retval = 1; + break; case G_TYPE_INT64: - if (g_value_get_int64 (&a_value) < g_value_get_int64 (&b_value)) - retval = -1; - else if (g_value_get_int64 (&a_value) == g_value_get_int64 (&b_value)) - retval = 0; - else - retval = 1; - break; + if (list1->data.v_int64 < list2->data.v_int64) + retval = -1; + else if (list1->data.v_int64 == list2->data.v_int64) + retval = 0; + else + retval = 1; + break; case G_TYPE_UINT64: - if (g_value_get_uint64 (&a_value) < g_value_get_uint64 (&b_value)) - retval = -1; - else if (g_value_get_uint64 (&a_value) == g_value_get_uint64 (&b_value)) - retval = 0; - else - retval = 1; - break; - case G_TYPE_ENUM: - /* this is somewhat bogus. */ - if (g_value_get_enum (&a_value) < g_value_get_enum (&b_value)) - retval = -1; - else if (g_value_get_enum (&a_value) == g_value_get_enum (&b_value)) - retval = 0; - else - retval = 1; - break; - case G_TYPE_FLAGS: - /* this is even more bogus. */ - if (g_value_get_flags (&a_value) < g_value_get_flags (&b_value)) - retval = -1; - else if (g_value_get_flags (&a_value) == g_value_get_flags (&b_value)) - retval = 0; - else - retval = 1; - break; + if (list1->data.v_uint64 < list2->data.v_uint64) + retval = -1; + else if (list1->data.v_uint64 == list2->data.v_uint64) + retval = 0; + else + retval = 1; + break; case G_TYPE_FLOAT: - if (g_value_get_float (&a_value) < g_value_get_float (&b_value)) - retval = -1; - else if (g_value_get_float (&a_value) == g_value_get_float (&b_value)) - retval = 0; - else - retval = 1; - break; + if (list1->data.v_float < list2->data.v_float) + retval = -1; + else if (list1->data.v_float == list2->data.v_float) + retval = 0; + else + retval = 1; + break; case G_TYPE_DOUBLE: - if (g_value_get_double (&a_value) < g_value_get_double (&b_value)) - retval = -1; - else if (g_value_get_double (&a_value) == g_value_get_double (&b_value)) - retval = 0; - else - retval = 1; - break; + if (list1->data.v_double < list2->data.v_double) + retval = -1; + else if (list1->data.v_double == list2->data.v_double) + retval = 0; + else + retval = 1; + break; case G_TYPE_STRING: - stra = g_value_get_string (&a_value); - strb = g_value_get_string (&b_value); - if (stra == NULL) stra = ""; - if (strb == NULL) strb = ""; - retval = g_utf8_collate (stra, strb); - break; + stra = list1->data.v_pointer; + strb = list2->data.v_pointer; + if (stra == NULL) stra = ""; + if (strb == NULL) strb = ""; + retval = fast_string_compare (stra, strb); + break; case G_TYPE_POINTER: case G_TYPE_BOXED: case G_TYPE_OBJECT: @@ -462,9 +453,6 @@ _foo_tree_data_list_compare_func (GtkTreeModel *model, break; } - g_value_unset (&a_value); - g_value_unset (&b_value); - return retval; } @@ -1608,7 +1608,7 @@ apply_workarounds (void) * environment variable instead. */ if (!getenv ("G_SLICE")) - putenv ("G_SLICE=always_malloc"); + putenv ("G_SLICE=always-malloc"); /* Accessibility prevents sysprof from working reliably, so * disable it. Specifically, it |