summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSøren Sandmann Pedersen <sandmann@daimi.au.dk>2010-11-10 05:52:13 -0500
committerSøren Sandmann Pedersen <sandmann@daimi.au.dk>2011-06-29 02:48:22 -0400
commitf5773082751d4d94965910fe2591aaeecdb06b97 (patch)
tree633b75ae9d498c55b682ff57cca53b5f51803bb7
parent1d22fff69fb539119fcf26a31a2f9147307e0b8f (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.c206
-rw-r--r--sysprof.c2
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;
}
diff --git a/sysprof.c b/sysprof.c
index c8dd30d..f7293b5 100644
--- a/sysprof.c
+++ b/sysprof.c
@@ -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