]> git.proxmox.com Git - libgit2.git/commitdiff
Large merge perf test.
authorJeff Hostetler <jeffhost@microsoft.com>
Fri, 6 Feb 2015 20:45:59 +0000 (15:45 -0500)
committerJeff Hostetler <jeffhost@microsoft.com>
Fri, 6 Feb 2015 20:45:59 +0000 (15:45 -0500)
tests/perf/helper__perf__do_merge.c [new file with mode: 0644]
tests/perf/helper__perf__do_merge.h [new file with mode: 0644]
tests/perf/helper__perf__timer.c [new file with mode: 0644]
tests/perf/helper__perf__timer.h [new file with mode: 0644]
tests/perf/merge.c [new file with mode: 0644]

diff --git a/tests/perf/helper__perf__do_merge.c b/tests/perf/helper__perf__do_merge.c
new file mode 100644 (file)
index 0000000..0022185
--- /dev/null
@@ -0,0 +1,78 @@
+#include "clar_libgit2.h"
+#include "helper__perf__do_merge.h"
+#include "helper__perf__timer.h"
+
+static git_repository * g_repo;
+
+void perf__do_merge(const char *fixture,
+                                       const char *test_name,
+                                       const char *id_a,
+                                       const char *id_b)
+{
+       git_checkout_options checkout_opts = GIT_CHECKOUT_OPTIONS_INIT;
+       git_clone_options clone_opts = GIT_CLONE_OPTIONS_INIT;
+       git_merge_options merge_opts = GIT_MERGE_OPTIONS_INIT;
+       git_oid oid_a;
+       git_oid oid_b;
+       git_reference *ref_branch_a = NULL;
+       git_reference *ref_branch_b = NULL;
+       git_commit *commit_a = NULL;
+       git_commit *commit_b = NULL;
+       git_annotated_commit *annotated_commits[1] = { NULL };
+       perf_timer t_total = PERF_TIMER_INIT;
+       perf_timer t_clone = PERF_TIMER_INIT;
+       perf_timer t_checkout = PERF_TIMER_INIT;
+       perf_timer t_merge = PERF_TIMER_INIT;
+
+       perf__timer__start(&t_total);
+
+       checkout_opts.checkout_strategy = GIT_CHECKOUT_SAFE_CREATE;
+       clone_opts.checkout_opts = checkout_opts;
+       cl_git_pass(git_signature_now(&clone_opts.signature, "Me", "foo@example.com"));
+
+       perf__timer__start(&t_clone);
+       cl_git_pass(git_clone(&g_repo, fixture, test_name, &clone_opts));
+       perf__timer__stop(&t_clone);
+       
+       git_oid_fromstr(&oid_a, id_a);
+       cl_git_pass(git_commit_lookup(&commit_a, g_repo, &oid_a));
+       cl_git_pass(git_branch_create(&ref_branch_a, g_repo,
+                                                                 "A", commit_a,
+                                                                 0, NULL, NULL));
+
+       perf__timer__start(&t_checkout);
+       cl_git_pass(git_checkout_tree(g_repo, (git_object*)commit_a, &checkout_opts));
+       perf__timer__stop(&t_checkout);
+
+       cl_git_pass(git_repository_set_head(g_repo,
+                                                                               git_reference_name(ref_branch_a),
+                                                                               NULL, NULL));
+
+       git_oid_fromstr(&oid_b, id_b);
+       cl_git_pass(git_commit_lookup(&commit_b, g_repo, &oid_b));
+       cl_git_pass(git_branch_create(&ref_branch_b, g_repo,
+                                                                 "B", commit_b,
+                                                                 0, NULL, NULL));
+
+       cl_git_pass(git_annotated_commit_lookup(&annotated_commits[0], g_repo, &oid_b));
+
+       perf__timer__start(&t_merge);
+       cl_git_pass(git_merge(g_repo,
+                                                 (const git_annotated_commit **)annotated_commits, 1,
+                                                 &merge_opts, &checkout_opts));
+       perf__timer__stop(&t_merge);
+
+       git_reference_free(ref_branch_a);
+       git_reference_free(ref_branch_b);
+       git_commit_free(commit_a);
+       git_commit_free(commit_b);
+       git_annotated_commit_free(annotated_commits[0]);
+       git_repository_free(g_repo);
+
+       perf__timer__stop(&t_total);
+
+       perf__timer__report(&t_clone, "%s: clone", test_name);
+       perf__timer__report(&t_checkout, "%s: checkout", test_name);
+       perf__timer__report(&t_merge, "%s: merge", test_name);
+       perf__timer__report(&t_total, "%s: total", test_name);
+}
diff --git a/tests/perf/helper__perf__do_merge.h b/tests/perf/helper__perf__do_merge.h
new file mode 100644 (file)
index 0000000..4a4723d
--- /dev/null
@@ -0,0 +1,4 @@
+void perf__do_merge(const char *fixture,
+                                       const char *test_name,
+                                       const char *id_a,
+                                       const char *id_b);
diff --git a/tests/perf/helper__perf__timer.c b/tests/perf/helper__perf__timer.c
new file mode 100644 (file)
index 0000000..8a7ed09
--- /dev/null
@@ -0,0 +1,73 @@
+#include "clar_libgit2.h"
+#include "helper__perf__timer.h"
+
+#if defined(GIT_WIN32)
+
+void perf__timer__start(perf_timer *t)
+{
+       QueryPerformanceCounter(&t->time_started);
+}
+
+void perf__timer__stop(perf_timer *t)
+{
+       LARGE_INTEGER time_now;
+       QueryPerformanceCounter(&time_now);
+
+       t->sum.QuadPart += (time_now.QuadPart - t->time_started.QuadPart);
+}
+
+void perf__timer__report(perf_timer *t, const char *fmt, ...)
+{
+       va_list arglist;
+       LARGE_INTEGER freq;
+       double fraction;
+
+       QueryPerformanceFrequency(&freq);
+
+       fraction = ((double)t->sum.QuadPart) / ((double)freq.QuadPart);
+
+       printf("%10.3f: ", fraction);
+
+       va_start(arglist, fmt);
+       vprintf(fmt, arglist);
+       va_end(arglist);
+
+       printf("\n");
+}
+
+#else
+
+#include <sys/time.h>
+
+static uint32_t now_in_ms(void)
+{
+       struct timeval now;
+       gettimeofday(&now, NULL);
+       return (uint32_t)((now.tv_sec * 1000) + (now.tv_usec / 1000));
+}
+
+void perf__timer__start(perf_timer *t)
+{
+       t->time_started = now_in_ms();
+}
+
+void perf__timer__stop(perf_timer *t)
+{
+       uint32_t now = now_in_ms();
+       t->sum += (now - t->time_started);
+}
+
+void perf__timer__report(perf_timer *t, const char *fmt, ...)
+{
+       va_list arglist;
+
+       printf("%10.3f: ", ((double)t->sum) / 1000);
+
+       va_start(arglist, fmt);
+       vprintf(fmt, arglist);
+       va_end(arglist);
+
+       printf("\n");
+}
+
+#endif
diff --git a/tests/perf/helper__perf__timer.h b/tests/perf/helper__perf__timer.h
new file mode 100644 (file)
index 0000000..5aff4b1
--- /dev/null
@@ -0,0 +1,27 @@
+#if defined(GIT_WIN32)
+
+struct perf__timer
+{
+       LARGE_INTEGER sum;
+       LARGE_INTEGER time_started;
+};
+
+#define PERF_TIMER_INIT {0}
+
+#else
+
+struct perf__timer
+{
+       uint32_t sum;
+       uint32_t time_started;
+};
+
+#define PERF_TIMER_INIT {0}
+
+#endif
+
+typedef struct perf__timer perf_timer;
+
+void perf__timer__start(perf_timer *t);
+void perf__timer__stop(perf_timer *t);
+void perf__timer__report(perf_timer *t, const char *fmt, ...);
diff --git a/tests/perf/merge.c b/tests/perf/merge.c
new file mode 100644 (file)
index 0000000..b2ef082
--- /dev/null
@@ -0,0 +1,44 @@
+#include "clar_libgit2.h"
+#include "helper__perf__do_merge.h"
+
+/* This test requires a large repo with many files.
+ * It doesn't care about the contents, just the size.
+ * 
+ * For now, we use the LibGit2 repo containing the
+ * source tree because it is already here.
+ *
+ * `find . | wc -l` reports 5128.
+ * 
+ */
+#define SRC_REPO (cl_fixture("../.."))
+
+/* We need 2 arbitrary commits within that repo
+ * that have a large number of changed files.
+ * Again, we don't care about the actual contents,
+ * just the size.
+ *
+ * For now, we use these public branches:
+ * maint/v0.21 d853fb9f24e0fe63b3dce9fbc04fd9cfe17a030b Always checkout with case sensitive iterator
+ * maint/v0.22 1ce9ea3ba9b4fa666602d52a5281d41a482cc58b checkout tests: cleanup realpath impl on Win32
+ *
+ */
+#define ID_BRANCH_A "d853fb9f24e0fe63b3dce9fbc04fd9cfe17a030b"
+#define ID_BRANCH_B "1ce9ea3ba9b4fa666602d52a5281d41a482cc58b"
+
+
+void test_perf_merge__initialize(void)
+{
+}
+
+void test_perf_merge__cleanup(void)
+{
+}
+
+void test_perf_merge__m1(void)
+{
+#if 1
+       cl_skip();
+#else
+       perf__do_merge(SRC_REPO, "m1", ID_BRANCH_A, ID_BRANCH_B);
+#endif
+}