]> git.ipfire.org Git - thirdparty/git.git/commitdiff
refs/reftable: precompute prefix length
authorPatrick Steinhardt <ps@pks.im>
Mon, 4 Mar 2024 10:49:40 +0000 (11:49 +0100)
committerJunio C Hamano <gitster@pobox.com>
Mon, 4 Mar 2024 18:19:58 +0000 (10:19 -0800)
We're recomputing the prefix length on every iteration of the ref
iterator. Precompute it for another speedup when iterating over 1
million refs:

    Benchmark 1: show-ref: single matching ref (revision = HEAD~)
      Time (mean ± σ):     100.3 ms ±   3.7 ms    [User: 97.3 ms, System: 2.8 ms]
      Range (min … max):    97.5 ms … 139.7 ms    1000 runs

    Benchmark 2: show-ref: single matching ref (revision = HEAD)
      Time (mean ± σ):      95.8 ms ±   3.4 ms    [User: 92.9 ms, System: 2.8 ms]
      Range (min … max):    93.0 ms … 121.9 ms    1000 runs

    Summary
      show-ref: single matching ref (revision = HEAD) ran
        1.05 ± 0.05 times faster than show-ref: single matching ref (revision = HEAD~)

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
refs/reftable-backend.c

index a14f2ad7f4545230887b433dd72712b30a38fd40..4d27fdde541f1ee5ab8f555e20b5de28b1c11144 100644 (file)
@@ -346,6 +346,7 @@ struct reftable_ref_iterator {
        struct object_id oid;
 
        const char *prefix;
+       size_t prefix_len;
        unsigned int flags;
        int err;
 };
@@ -371,8 +372,8 @@ static int reftable_ref_iterator_advance(struct ref_iterator *ref_iterator)
                if (!starts_with(iter->ref.refname, "refs/"))
                        continue;
 
-               if (iter->prefix &&
-                   strncmp(iter->prefix, iter->ref.refname, strlen(iter->prefix))) {
+               if (iter->prefix_len &&
+                   strncmp(iter->prefix, iter->ref.refname, iter->prefix_len)) {
                        iter->err = 1;
                        break;
                }
@@ -481,6 +482,7 @@ static struct reftable_ref_iterator *ref_iterator_for_stack(struct reftable_ref_
        iter = xcalloc(1, sizeof(*iter));
        base_ref_iterator_init(&iter->base, &reftable_ref_iterator_vtable, 1);
        iter->prefix = prefix;
+       iter->prefix_len = prefix ? strlen(prefix) : 0;
        iter->base.oid = &iter->oid;
        iter->flags = flags;
        iter->refs = refs;