[gtk/arraystore-perf: 2/4] wip: Add the old stringlist for comparsion
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/arraystore-perf: 2/4] wip: Add the old stringlist for comparsion
- Date: Fri, 3 Jul 2020 23:56:05 +0000 (UTC)
commit 373c06b14808032eb0ac4c451b04a6563dad7b79
Author: Matthias Clasen <mclasen redhat com>
Date: Wed Jul 1 17:51:26 2020 -0400
wip: Add the old stringlist for comparsion
testsuite/gtk/gtkstringlist.c | 222 ++++++++++++++++++++++++++++++++++
testsuite/gtk/gtkstringlist.h | 62 ++++++++++
testsuite/gtk/listmodel-performance.c | 102 +++++++++++++---
testsuite/gtk/meson.build | 2 +-
4 files changed, 372 insertions(+), 16 deletions(-)
---
diff --git a/testsuite/gtk/gtkstringlist.c b/testsuite/gtk/gtkstringlist.c
new file mode 100644
index 0000000000..c7473485ed
--- /dev/null
+++ b/testsuite/gtk/gtkstringlist.c
@@ -0,0 +1,222 @@
+/*
+ * Copyright © 2020 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Matthias Clasen <mclasen redhat com>
+ */
+
+#include "config.h"
+
+#include <gtk.h>
+#include "gtkstringlist.h"
+
+struct _GtkStringList2
+{
+ GObject parent_instance;
+
+ GSequence *items;
+};
+
+struct _GtkStringList2Class
+{
+ GObjectClass parent_class;
+};
+
+static GType
+gtk_string_list2_get_item_type (GListModel *list)
+{
+ return G_TYPE_OBJECT;
+}
+
+static guint
+gtk_string_list2_get_n_items (GListModel *list)
+{
+ GtkStringList2 *self = GTK_STRING_LIST2 (list);
+
+ return g_sequence_get_length (self->items);
+}
+
+static gpointer
+gtk_string_list2_get_item (GListModel *list,
+ guint position)
+{
+ GtkStringList2 *self = GTK_STRING_LIST2 (list);
+ GSequenceIter *iter;
+
+ iter = g_sequence_get_iter_at_pos (self->items, position);
+
+ if (g_sequence_iter_is_end (iter))
+ return NULL;
+ else
+ return g_object_ref (g_sequence_get (iter));
+}
+
+static void
+gtk_string_list2_model_init (GListModelInterface *iface)
+{
+ iface->get_item_type = gtk_string_list2_get_item_type;
+ iface->get_n_items = gtk_string_list2_get_n_items;
+ iface->get_item = gtk_string_list2_get_item;
+}
+
+G_DEFINE_TYPE_WITH_CODE (GtkStringList2, gtk_string_list2, G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (G_TYPE_LIST_MODEL,
+ gtk_string_list2_model_init))
+
+static void
+gtk_string_list2_dispose (GObject *object)
+{
+ GtkStringList2 *self = GTK_STRING_LIST2 (object);
+
+ g_clear_pointer (&self->items, g_sequence_free);
+
+ G_OBJECT_CLASS (gtk_string_list2_parent_class)->dispose (object);
+}
+
+static void
+gtk_string_list2_class_init (GtkStringList2Class *class)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (class);
+
+ gobject_class->dispose = gtk_string_list2_dispose;
+}
+
+static void
+gtk_string_list2_init (GtkStringList2 *self)
+{
+ self->items = g_sequence_new (g_object_unref);
+}
+
+GtkStringList2 *
+gtk_string_list2_new (const char * const *strings)
+{
+ GtkStringList2 *self;
+
+ self = g_object_new (GTK_TYPE_STRING_LIST2, NULL);
+
+ gtk_string_list2_splice (self, 0, 0, strings);
+
+ return self;
+}
+
+typedef struct {
+ GObject obj;
+ char *str;
+} StrObj;
+
+static GtkStringObject *
+string_object_new (const char *string)
+{
+ GtkStringObject *s;
+
+ s = g_object_new (GTK_TYPE_STRING_OBJECT, NULL);
+ ((StrObj*)s)->str = g_strdup (string);
+
+ return s;
+}
+
+void
+gtk_string_list2_splice (GtkStringList2 *self,
+ guint position,
+ guint n_removals,
+ const char * const *additions)
+{
+ guint n_items;
+ guint add;
+ GSequenceIter *it;
+
+ g_return_if_fail (GTK_IS_STRING_LIST2 (self));
+ g_return_if_fail (position + n_removals >= position); /* overflow */
+
+ n_items = g_sequence_get_length (self->items);
+ g_return_if_fail (position + n_removals <= n_items);
+
+ it = g_sequence_get_iter_at_pos (self->items, position);
+
+ if (n_removals)
+ {
+ GSequenceIter *end;
+
+ end = g_sequence_iter_move (it, n_removals);
+ g_sequence_remove_range (it, end);
+
+ it = end;
+ }
+
+ if (additions)
+ {
+ for (add = 0; additions[add]; add++)
+ {
+ g_sequence_insert_before (it, string_object_new (additions[add]));
+ }
+ }
+ else
+ add = 0;
+
+ if (n_removals || add)
+ g_list_model_items_changed (G_LIST_MODEL (self), position, n_removals, add);
+}
+
+void
+gtk_string_list2_append (GtkStringList2 *self,
+ const char *string)
+{
+ guint n_items;
+
+ g_return_if_fail (GTK_IS_STRING_LIST2 (self));
+
+ n_items = g_sequence_get_length (self->items);
+ g_sequence_append (self->items, string_object_new (string));
+
+ g_list_model_items_changed (G_LIST_MODEL (self), n_items, 0, 1);
+}
+
+void
+gtk_string_list2_remove (GtkStringList2 *self,
+ guint position)
+{
+ GSequenceIter *iter;
+
+ g_return_if_fail (GTK_IS_STRING_LIST2 (self));
+
+ iter = g_sequence_get_iter_at_pos (self->items, position);
+ g_return_if_fail (!g_sequence_iter_is_end (iter));
+
+ g_sequence_remove (iter);
+
+ g_list_model_items_changed (G_LIST_MODEL (self), position, 1, 0);
+}
+
+const char *
+gtk_string_list2_get_string (GtkStringList2 *self,
+ guint position)
+{
+ GSequenceIter *iter;
+
+ g_return_val_if_fail (GTK_IS_STRING_LIST (self), NULL);
+
+ iter = g_sequence_get_iter_at_pos (self->items, position);
+
+ if (g_sequence_iter_is_end (iter))
+ {
+ return NULL;
+ }
+ else
+ {
+ GtkStringObject *obj = g_sequence_get (iter);
+
+ return gtk_string_object_get_string (obj);
+ }
+}
diff --git a/testsuite/gtk/gtkstringlist.h b/testsuite/gtk/gtkstringlist.h
new file mode 100644
index 0000000000..cf529694a3
--- /dev/null
+++ b/testsuite/gtk/gtkstringlist.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright © 2020 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Matthias Clasen <mclasen redhat com>
+ */
+
+#ifndef __GTK_STRING_LIST2_H__
+#define __GTK_STRING_LIST2_H__
+
+#include <gio/gio.h>
+/* for GDK_AVAILABLE_IN_ALL */
+#include <gdk/gdk.h>
+
+
+G_BEGIN_DECLS
+
+#define GTK_TYPE_STRING_LIST2 (gtk_string_list2_get_type ())
+
+GDK_AVAILABLE_IN_ALL
+G_DECLARE_FINAL_TYPE (GtkStringList2, gtk_string_list2, GTK, STRING_LIST2, GObject)
+
+GDK_AVAILABLE_IN_ALL
+GtkStringList2 * gtk_string_list2_new (const char * const *strings);
+
+GDK_AVAILABLE_IN_ALL
+void gtk_string_list2_append (GtkStringList2 *self,
+ const char *string);
+
+GDK_AVAILABLE_IN_ALL
+void gtk_string_list2_take (GtkStringList2 *self,
+ char *string);
+
+GDK_AVAILABLE_IN_ALL
+void gtk_string_list2_remove (GtkStringList2 *self,
+ guint position);
+
+GDK_AVAILABLE_IN_ALL
+void gtk_string_list2_splice (GtkStringList2 *self,
+ guint position,
+ guint n_removals,
+ const char * const *additions);
+
+GDK_AVAILABLE_IN_ALL
+const char * gtk_string_list2_get_string (GtkStringList2 *self,
+ guint position);
+
+G_END_DECLS
+
+#endif /* __GTK_STRING_LIST2_H__ */
diff --git a/testsuite/gtk/listmodel-performance.c b/testsuite/gtk/listmodel-performance.c
index bf2abf7aaf..d56cae6779 100644
--- a/testsuite/gtk/listmodel-performance.c
+++ b/testsuite/gtk/listmodel-performance.c
@@ -1,5 +1,7 @@
#include <gtk/gtk.h>
+#include "gtkstringlist.h"
+
static GObject *
get_object (const char *string)
{
@@ -36,6 +38,26 @@ make_list_store (guint n_items)
return G_LIST_MODEL (store);
}
+static GListModel *
+make_string_list2 (guint n_items)
+{
+ GtkStringList2 *store;
+ guint i;
+
+ store = gtk_string_list2_new (NULL);
+
+ for (i = 0; i < n_items; i++)
+ {
+ char *string;
+
+ string = g_strdup_printf ("item %d", i);
+ gtk_string_list2_append (store, string);
+ g_free (string);
+ }
+
+ return G_LIST_MODEL (store);
+}
+
static GListModel *
make_string_list (guint n_items)
{
@@ -70,6 +92,8 @@ do_random_access (const char *kind,
if (strcmp (kind, "liststore") == 0)
model = make_list_store (size);
else if (strcmp (kind, "stringlist") == 0)
+ model = make_string_list2 (size);
+ else if (strcmp (kind, "array stringlist") == 0)
model = make_string_list (size);
else
g_error ("unsupported: %s", kind);
@@ -87,7 +111,46 @@ do_random_access (const char *kind,
end = g_get_monotonic_time ();
- g_print ("\"%s\", %u, %g\n",
+ g_print ("\"random access\",\"%s\", %u, %g\n",
+ kind,
+ size,
+ iterations / (((double)(end - start)) / G_TIME_SPAN_SECOND));
+
+ g_object_unref (model);
+}
+
+static void
+do_linear_access (const char *kind,
+ guint size)
+{
+ GListModel *model;
+ guint i;
+ GtkStringObject *obj;
+ gint64 start, end;
+ guint iterations = 10000000;
+
+ if (strcmp (kind, "liststore") == 0)
+ model = make_list_store (size);
+ else if (strcmp (kind, "stringlist") == 0)
+ model = make_string_list2 (size);
+ else if (strcmp (kind, "array stringlist") == 0)
+ model = make_string_list (size);
+ else
+ g_error ("unsupported: %s", kind);
+
+ start = g_get_monotonic_time ();
+
+ for (i = 0; i < iterations; i++)
+ {
+ obj = g_list_model_get_item (model, i % size);
+ if (g_getenv ("PRINT_ACCESS"))
+ g_print ("%s", gtk_string_object_get_string (obj));
+ g_object_unref (obj);
+ }
+
+ end = g_get_monotonic_time ();
+
+ g_print ("\"linear access\", \"%s\", %u, %g\n",
kind,
size,
iterations / (((double)(end - start)) / G_TIME_SPAN_SECOND));
@@ -98,20 +161,27 @@ do_random_access (const char *kind,
static void
random_access (void)
{
- do_random_access ("liststore", 1e1);
- do_random_access ("liststore", 1e2);
- do_random_access ("liststore", 1e3);
- do_random_access ("liststore", 1e4);
- do_random_access ("liststore", 1e5);
- do_random_access ("liststore", 1e6);
- do_random_access ("liststore", 1e7);
- do_random_access ("stringlist", 1e1);
- do_random_access ("stringlist", 1e2);
- do_random_access ("stringlist", 1e3);
- do_random_access ("stringlist", 1e4);
- do_random_access ("stringlist", 1e5);
- do_random_access ("stringlist", 1e6);
- do_random_access ("stringlist", 1e7);
+ const char *kind[] = { "liststore", "stringlist", "array stringlist" };
+ int sizes = 22;
+ int size;
+ int i, j;
+
+ for (i = 0; i < G_N_ELEMENTS (kind); i++)
+ for (j = 0, size = 2; j < sizes; j++, size *= 2)
+ do_random_access (kind[i], size);
+}
+
+static void
+linear_access (void)
+{
+ const char *kind[] = { "liststore", "stringlist", "array stringlist" };
+ int sizes = 22;
+ int size;
+ int i, j;
+
+ for (i = 0; i < G_N_ELEMENTS (kind); i++)
+ for (j = 0, size = 2; j < sizes; j++, size *= 2)
+ do_linear_access (kind[i], size);
}
int
@@ -119,7 +189,9 @@ main (int argc, char *argv[])
{
gtk_test_init (&argc, &argv);
+ g_print ("\"test\",\"model\",\"model size\",\"accesses/s\"");
g_test_add_func ("/liststore/random-access", random_access);
+ g_test_add_func ("/liststore/linear-access", linear_access);
return g_test_run ();
}
diff --git a/testsuite/gtk/meson.build b/testsuite/gtk/meson.build
index 1baa425b3f..8e952c3a49 100644
--- a/testsuite/gtk/meson.build
+++ b/testsuite/gtk/meson.build
@@ -78,7 +78,7 @@ tests = [
['vector'],
['widgetorder'],
['widget-refcount'],
- ['listmodel-performance'],
+ ['listmodel-performance', ['listmodel-performance.c','gtkstringlist.c']]
]
# Tests that are expected to fail
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]