Skip to content

Commit 71d9a2e

Browse files
pks-tgitster
authored andcommitted
reftable/record: reuse refname when decoding
When decoding a reftable record we will first release the user-provided record and then decode the new record into it. This is quite inefficient as we basically need to reallocate at least the refname every time. Refactor the function to start tracking the refname capacity. Like this, we can stow away the refname, release, restore and then grow the refname to the required number of bytes via `REFTABLE_ALLOC_GROW()`. This refactoring is safe to do because all functions that assigning to the refname will first call `reftable_ref_record_release()`, which will zero out the complete record after releasing memory. This change results in a nice speedup when iterating over 1 million refs: Benchmark 1: show-ref: single matching ref (revision = HEAD~) Time (mean ± σ): 124.0 ms ± 3.9 ms [User: 121.1 ms, System: 2.7 ms] Range (min … max): 120.4 ms … 152.7 ms 1000 runs Benchmark 2: show-ref: single matching ref (revision = HEAD) Time (mean ± σ): 114.4 ms ± 3.7 ms [User: 111.5 ms, System: 2.7 ms] Range (min … max): 111.0 ms … 152.1 ms 1000 runs Summary show-ref: single matching ref (revision = HEAD) ran 1.08 ± 0.05 times faster than show-ref: single matching ref (revision = HEAD~) Furthermore, with this change we now perform a mostly constant number of allocations when iterating. Before this change: HEAP SUMMARY: in use at exit: 13,603 bytes in 125 blocks total heap usage: 1,006,620 allocs, 1,006,495 frees, 25,398,363 bytes allocated After this change: HEAP SUMMARY: in use at exit: 13,603 bytes in 125 blocks total heap usage: 6,623 allocs, 6,498 frees, 509,592 bytes allocated Signed-off-by: Patrick Steinhardt <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 080f8c4 commit 71d9a2e

File tree

2 files changed

+13
-4
lines changed

2 files changed

+13
-4
lines changed

reftable/record.c

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -368,16 +368,24 @@ static int reftable_ref_record_decode(void *rec, struct strbuf key,
368368
struct reftable_ref_record *r = rec;
369369
struct string_view start = in;
370370
uint64_t update_index = 0;
371-
int n = get_var_int(&update_index, &in);
371+
const char *refname = NULL;
372+
size_t refname_cap = 0;
373+
int n;
374+
375+
assert(hash_size > 0);
376+
377+
n = get_var_int(&update_index, &in);
372378
if (n < 0)
373379
return n;
374380
string_view_consume(&in, n);
375381

382+
SWAP(refname, r->refname);
383+
SWAP(refname_cap, r->refname_cap);
376384
reftable_ref_record_release(r);
385+
SWAP(r->refname, refname);
386+
SWAP(r->refname_cap, refname_cap);
377387

378-
assert(hash_size > 0);
379-
380-
r->refname = reftable_malloc(key.len + 1);
388+
REFTABLE_ALLOC_GROW(r->refname, key.len + 1, r->refname_cap);
381389
memcpy(r->refname, key.buf, key.len);
382390
r->refname[key.len] = 0;
383391

reftable/reftable-record.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ license that can be found in the LICENSE file or at
2222
/* reftable_ref_record holds a ref database entry target_value */
2323
struct reftable_ref_record {
2424
char *refname; /* Name of the ref, malloced. */
25+
size_t refname_cap;
2526
uint64_t update_index; /* Logical timestamp at which this value is
2627
* written */
2728

0 commit comments

Comments
 (0)