[gtk/wip/otte/vector] testsuite: Add some vector performance tests
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/wip/otte/vector] testsuite: Add some vector performance tests
- Date: Sun, 5 Jul 2020 19:30:50 +0000 (UTC)
commit 50b13e5f8b136e6b1e30ea532df589f8c19b2f3b
Author: Benjamin Otte <otte redhat com>
Date: Sun Jul 5 20:11:50 2020 +0200
testsuite: Add some vector performance tests
They're not very conclusive though, because the testing isn't
fine-grained enough for these microbenchmarks.
testsuite/gtk/meson.build | 1 +
testsuite/gtk/vector-performance.c | 443 +++++++++++++++++++++++++++++++++++++
2 files changed, 444 insertions(+)
---
diff --git a/testsuite/gtk/meson.build b/testsuite/gtk/meson.build
index f5ed09a8c1..16602b4ff0 100644
--- a/testsuite/gtk/meson.build
+++ b/testsuite/gtk/meson.build
@@ -75,6 +75,7 @@ tests = [
['displayclose'],
['revealer-size'],
['vector'],
+ ['vector-performance'],
['widgetorder'],
['widget-refcount'],
]
diff --git a/testsuite/gtk/vector-performance.c b/testsuite/gtk/vector-performance.c
new file mode 100644
index 0000000000..2f743a4000
--- /dev/null
+++ b/testsuite/gtk/vector-performance.c
@@ -0,0 +1,443 @@
+#include <gtk/gtk.h>
+
+#define GTK_VECTOR_ELEMENT_TYPE gpointer
+#define GTK_VECTOR_NAME pointer_vector
+#define GTK_VECTOR_TYPE_NAME PointerVector
+#include "../../gtk/gtkvectorimpl.c"
+
+#define GTK_VECTOR_ELEMENT_TYPE gpointer
+#define GTK_VECTOR_NAME prealloc_vector
+#define GTK_VECTOR_TYPE_NAME PreallocVector
+#define GTK_VECTOR_PREALLOC 1024
+#include "../../gtk/gtkvectorimpl.c"
+
+static inline guint
+quick_random (guint prev)
+{
+ prev ^= prev << 13;
+ prev ^= prev >> 17;
+ prev ^= prev << 5;
+ return prev;
+}
+
+typedef struct {
+ const char *name;
+ gsize stack_space;
+ gpointer (* create) (gpointer space, gsize size);
+ void (* free) (gpointer array);
+ void (* reserve) (gpointer array, gsize size);
+ gpointer (* get) (gpointer array, gsize pos);
+ void (* append) (gpointer array, gpointer data);
+ void (* insert) (gpointer array, gsize pos, gpointer data);
+} Array;
+
+static gpointer
+create_ptrarray (gpointer space,
+ gsize size)
+{
+ return g_ptr_array_sized_new (size);
+}
+
+static void
+free_ptrarray (gpointer array)
+{
+ g_ptr_array_free (array, TRUE);
+}
+
+static void
+reserve_ptrarray (gpointer array,
+ gsize size)
+{
+ gsize length = ((GPtrArray *) array)->len;
+
+ if (length >= size)
+ return;
+
+ g_ptr_array_set_size (array, size);
+ g_ptr_array_set_size (array, length);
+}
+
+static gpointer
+get_ptrarray (gpointer array,
+ gsize pos)
+{
+ return g_ptr_array_index ((GPtrArray *) array, pos);
+}
+
+static void
+append_ptrarray (gpointer array,
+ gpointer data)
+{
+ g_ptr_array_add (array, data);
+}
+
+static void
+insert_ptrarray (gpointer array,
+ gsize pos,
+ gpointer data)
+{
+ g_ptr_array_insert (array, pos, data);
+}
+
+static gpointer
+create_vector (gpointer space,
+ gsize size)
+{
+ pointer_vector_init (space);
+
+ if (size)
+ pointer_vector_reserve ((PointerVector *) space, size);
+
+ return space;
+}
+
+static void
+free_vector (gpointer array)
+{
+ pointer_vector_clear (array);
+}
+
+static void
+reserve_vector (gpointer array,
+ gsize size)
+{
+ pointer_vector_reserve (array, size);
+}
+
+static gpointer
+get_vector (gpointer array,
+ gsize pos)
+{
+ return pointer_vector_get (array, pos);
+}
+
+static void
+append_vector (gpointer array,
+ gpointer data)
+{
+ pointer_vector_append (array, data);
+}
+
+static void
+insert_vector (gpointer array,
+ gsize pos,
+ gpointer data)
+{
+ pointer_vector_splice (array, pos, 0, &data, 1);
+}
+
+static gpointer
+create_prealloc (gpointer space,
+ gsize size)
+{
+ prealloc_vector_init (space);
+
+ if (size)
+ prealloc_vector_reserve ((PreallocVector *) space, size);
+
+ return space;
+}
+
+static void
+free_prealloc (gpointer array)
+{
+ prealloc_vector_clear (array);
+}
+
+static void
+reserve_prealloc (gpointer array,
+ gsize size)
+{
+ prealloc_vector_reserve (array, size);
+}
+
+static gpointer
+get_prealloc (gpointer array,
+ gsize pos)
+{
+ return prealloc_vector_get (array, pos);
+}
+
+static void
+append_prealloc (gpointer array,
+ gpointer data)
+{
+ prealloc_vector_append (array, data);
+}
+
+static void
+insert_prealloc (gpointer array,
+ gsize pos,
+ gpointer data)
+{
+ prealloc_vector_splice (array, pos, 0, &data, 1);
+}
+
+static void
+do_random_access (const Array *klass,
+ guint random,
+ gsize size,
+ gsize max_size)
+{
+ gpointer stack;
+ gpointer array;
+ guint i;
+ guint position;
+ gint64 start, end;
+ guint iterations = 10000000;
+
+ size = pow (100 * 100 * 100 * 100, (double) size / max_size);
+
+ if (klass->stack_space)
+ stack = g_alloca (klass->stack_space);
+ else
+ stack = NULL;
+ array = klass->create (stack, size);
+ for (i = 0; i < size; i++)
+ klass->append (array, GSIZE_TO_POINTER (i));
+
+ start = g_get_monotonic_time ();
+
+ for (i = 0; i < iterations; i++)
+ {
+ position = random % size;
+ random = quick_random (random);
+ g_assert_cmpint (position, ==, GPOINTER_TO_SIZE (klass->get (array, position)));
+ }
+
+ end = g_get_monotonic_time ();
+
+ g_print ("\"random access\",\"%s\", %zu, %g\n",
+ klass->name,
+ size,
+ ((double)(end - start)) / iterations);
+
+ klass->free (array);
+}
+
+static void
+do_linear_access (const Array *klass,
+ guint random,
+ gsize size,
+ gsize max_size)
+{
+ gpointer stack;
+ gpointer array;
+ guint i;
+ gint64 start, end;
+ guint iterations = 1000000;
+
+ size = pow (100 * 100 * 100 * 100, (double) size / max_size);
+
+ if (klass->stack_space)
+ stack = g_alloca (klass->stack_space);
+ else
+ stack = NULL;
+ array = klass->create (stack, size);
+ for (i = 0; i < size; i++)
+ klass->append (array, GSIZE_TO_POINTER (i));
+
+ start = g_get_monotonic_time ();
+
+ for (i = 0; i < iterations; i++)
+ {
+ g_assert_cmpint (i % size, ==, GPOINTER_TO_SIZE (klass->get (array, i % size)));
+ }
+
+ end = g_get_monotonic_time ();
+
+ g_print ("\"linear access\", \"%s\", %zu, %g\n",
+ klass->name,
+ size,
+ ((double)(end - start)) / iterations);
+
+ klass->free (array);
+}
+
+static void
+do_append (const Array *klass,
+ guint random,
+ gsize size,
+ gsize max_size)
+{
+ gpointer stack;
+ gpointer array;
+ guint i;
+ gint64 start, end;
+ int iterations = 10000;
+
+ size = pow (100 * 1000 * 1000, (double) size / max_size);
+
+ if (klass->stack_space)
+ stack = g_alloca (klass->stack_space);
+ else
+ stack = NULL;
+ array = klass->create (stack, size);
+ for (i = 0; i < size; i++)
+ klass->append (array, GSIZE_TO_POINTER (i));
+
+ start = g_get_monotonic_time ();
+
+ for (i = size; i < size + iterations; i++)
+ {
+ klass->append (array, GSIZE_TO_POINTER (i));
+ }
+
+ end = g_get_monotonic_time ();
+
+ klass->free (array);
+
+ g_print ("\"append\", \"%s\", %zu, %g\n",
+ klass->name,
+ size,
+ ((double) (end - start)) / iterations);
+}
+
+static void
+do_insert (const Array *klass,
+ guint random,
+ gsize size,
+ gsize max_size)
+{
+ gpointer stack;
+ gpointer array;
+ guint i;
+ gint64 start, end;
+ int iterations = 10000;
+
+ size = pow (25 * 25 * 25 * 25, (double) size / max_size);
+
+ if (klass->stack_space)
+ stack = g_alloca (klass->stack_space);
+ else
+ stack = NULL;
+ array = klass->create (stack, size);
+ for (i = 0; i < size; i++)
+ klass->append (array, GSIZE_TO_POINTER (i));
+
+ start = g_get_monotonic_time ();
+
+ for (i = size; i < size + iterations; i++)
+ {
+ gsize position = random % size;
+ random = quick_random (random);
+
+ klass->insert (array, position, GSIZE_TO_POINTER (i));
+ }
+
+ end = g_get_monotonic_time ();
+
+ klass->free (array);
+
+ g_print ("\"insert\", \"%s\", %zu, %g\n",
+ klass->name,
+ size,
+ ((double) (end - start)) / iterations);
+}
+
+static void
+do_create (const Array *klass,
+ guint random,
+ gsize size,
+ gsize max_size)
+{
+ gpointer stack;
+ gpointer array;
+ gsize i, j;
+ gint64 start, end;
+ gsize iterations = 10000;
+
+ size = pow (16 * 16 * 16 * 16, (double) size / max_size);
+
+ if (klass->stack_space)
+ stack = g_alloca (klass->stack_space);
+ else
+ stack = NULL;
+
+ start = g_get_monotonic_time ();
+
+ for (i = 0; i < iterations; i++)
+ {
+ gsize position = random % size;
+ random = quick_random (random);
+
+ array = klass->create (stack, size);
+ for (j = 0; j < size; j++)
+ klass->append (array, GSIZE_TO_POINTER (i));
+
+ klass->insert (array, position, GSIZE_TO_POINTER (i));
+ klass->free (array);
+ }
+
+ end = g_get_monotonic_time ();
+
+ g_print ("\"create\", \"%s\", %zu, %g\n",
+ klass->name,
+ size,
+ ((double) (end - start)) / iterations);
+}
+
+const Array all_arrays[] = {
+ {
+ "ptrarray",
+ 0,
+ create_ptrarray,
+ free_ptrarray,
+ reserve_ptrarray,
+ get_ptrarray,
+ append_ptrarray,
+ insert_ptrarray
+ },
+ {
+ "vector",
+ sizeof (PointerVector),
+ create_vector,
+ free_vector,
+ reserve_vector,
+ get_vector,
+ append_vector,
+ insert_vector
+ },
+ {
+ "preallocated-vector",
+ sizeof (PreallocVector),
+ create_prealloc,
+ free_prealloc,
+ reserve_prealloc,
+ get_prealloc,
+ append_prealloc,
+ insert_prealloc
+ }
+};
+
+static void
+run_test (void (* test_func) (const Array *klass, guint random, gsize size, gsize max_size))
+{
+ int max_size = 4;
+ int size;
+ int i;
+ guint random = g_random_int ();
+
+ for (i = 0; i < G_N_ELEMENTS (all_arrays); i++)
+ {
+ for (size = 1; size <= max_size; size++)
+ {
+ test_func (&all_arrays[i], random, size, max_size);
+ }
+ }
+}
+
+int
+main (int argc, char *argv[])
+{
+ gtk_test_init (&argc, &argv);
+
+ g_print ("\"test\",\"model\",\"model size\",\"time\"\n");
+ run_test (do_random_access);
+ run_test (do_linear_access);
+ run_test (do_append);
+ run_test (do_insert);
+ run_test (do_create);
+
+ return g_test_run ();
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]