From d97ba7f6744012fb51127d5313543a10c5a60e43 Mon Sep 17 00:00:00 2001 From: Jeff Hostetler Date: Fri, 6 Feb 2015 15:45:59 -0500 Subject: [PATCH] Large merge perf test. --- tests/perf/helper__perf__do_merge.c | 78 +++++++++++++++++++++++++++++ tests/perf/helper__perf__do_merge.h | 4 ++ tests/perf/helper__perf__timer.c | 73 +++++++++++++++++++++++++++ tests/perf/helper__perf__timer.h | 27 ++++++++++ tests/perf/merge.c | 44 ++++++++++++++++ 5 files changed, 226 insertions(+) create mode 100644 tests/perf/helper__perf__do_merge.c create mode 100644 tests/perf/helper__perf__do_merge.h create mode 100644 tests/perf/helper__perf__timer.c create mode 100644 tests/perf/helper__perf__timer.h create mode 100644 tests/perf/merge.c diff --git a/tests/perf/helper__perf__do_merge.c b/tests/perf/helper__perf__do_merge.c new file mode 100644 index 000000000..00221851e --- /dev/null +++ b/tests/perf/helper__perf__do_merge.c @@ -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 index 000000000..4a4723da5 --- /dev/null +++ b/tests/perf/helper__perf__do_merge.h @@ -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 index 000000000..8a7ed09e8 --- /dev/null +++ b/tests/perf/helper__perf__timer.c @@ -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 + +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 index 000000000..5aff4b136 --- /dev/null +++ b/tests/perf/helper__perf__timer.h @@ -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 index 000000000..b2ef082eb --- /dev/null +++ b/tests/perf/merge.c @@ -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 +} -- 2.39.5