git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCH v2 7/8] reftable/merged: really reuse buffers to compute record keys

From
Junio C Hamano <gitster@pobox.com>
Date
Dec 28, 2023, 17:03 UTC
Message-ID
<xmqq8r5ei7jv.fsf@gitster.g>
In-Reply-To
<6313f8affdc136b183c1bd411d481efe5c676aee.1703743174.git.ps@pks.im>
Patrick Steinhardt <ps@pks.im> writes:
Show 6 quoted lines
> In 829231dc20 (reftable/merged: reuse buffer to compute record keys,
> 2023-12-11), we have refactored the merged iterator to reuse a set of
> buffers that it would otherwise have to reallocate on every single
> iteration. Unfortunately, there was a brown-paper-bag-style bug here as
> we continue to release these buffers after the iteration, and thus we
> have essentially gained nothing.

s/-style// perhaps. It took me more than just reading of the above but I needed to see the code before noticed that you are talking about strbuf_release(). Only after that I think I understood what you meant as a bug.

    With the change, instead of using a new "entry_key" strbuf for
    each iteration, the code now passes mi->entry_key to
    reftable_record_key(), which will reuse the existing .buf member
    of the strbuf to avoid reallcation.  But releasing the strbuf in
    each iteration defeats such optimization.

I suspect that a Git developer who will be reading "git log" output in 6 months and finds the above paragraph understands the problem and its fix better if the description hinted strbuf_reset() near where it mentions "release", something like:

    ... to reuse a pair of long-living strbufs by relying on the
    fact that reftable_record_key() tries to reuse its already
    allocated .buf member by calling strbuf_reset(), which should
    give us significantly fewer reallocation compared to the old
    code that used on-stack strbufs that are allocated for each and
    every iteration.  Unfortunately, we called strbuf_release() on
    these long-living strbufs that we meant to reuse, defeating the
    optimization.
or along that line, perhaps?
Other than that, a very reasonable fix.  Thanks for a pleasant read.
Show 34 quoted lines
> Fix this performance issue by not releasing those buffers on iteration
> anymore, where we instead rely on `merged_iter_close()` to release the
> buffers for us.
>
> Using `git show-ref --quiet` in a repository with ~350k refs this leads
> to a significant drop in allocations. Before:
>
>     HEAP SUMMARY:
>         in use at exit: 21,163 bytes in 193 blocks
>       total heap usage: 1,410,148 allocs, 1,409,955 frees, 61,976,068 bytes allocated
>
> After:
>
>     HEAP SUMMARY:
>         in use at exit: 21,163 bytes in 193 blocks
>       total heap usage: 708,058 allocs, 707,865 frees, 36,783,255 bytes allocated
>
> Signed-off-by: Patrick Steinhardt <ps@pks.im>
> ---
>  reftable/merged.c | 2 --
>  1 file changed, 2 deletions(-)
>
> diff --git a/reftable/merged.c b/reftable/merged.c
> index 556bb5c556..a28bb99aaf 100644
> --- a/reftable/merged.c
> +++ b/reftable/merged.c
> @@ -128,8 +128,6 @@ static int merged_iter_next_entry(struct merged_iter *mi,
>  
>  done:
>  	reftable_record_release(&entry.rec);
> -	strbuf_release(&mi->entry_key);
> -	strbuf_release(&mi->key);
>  	return err;
>  }
Previous: Patrick SteinhardtNext: Patrick Steinhardt
Message 20 of 36 in “reftable: fixes and optimizations (pt.2)”
  1. 0/7 reftable: fixes and optimizations (pt.2)Patrick Steinhardt, Dec 20, 2023
  2. 1/7 reftable/stack: do not overwrite errors when compactingPatrick Steinhardt, Dec 20, 2023
  3. 2/7 reftable/writer: fix index corruption when writing multiple indicesPatrick Steinhardt, Dec 20, 2023
  4. 3/7 reftable/record: constify some parts of the interfacePatrick Steinhardt, Dec 20, 2023
  5. 4/7 reftable/record: store "val1" hashes as static arraysPatrick Steinhardt, Dec 20, 2023
  6. Patrick SteinhardtDec 20, 2023
  7. 5/7 reftable/record: store "val2" hashes as static arraysPatrick Steinhardt, Dec 20, 2023
  8. 6/7 reftable/merged: really reuse buffers to compute record keysPatrick Steinhardt, Dec 20, 2023
  9. 7/7 reftable/merged: transfer ownership of records when iteratingPatrick Steinhardt, Dec 20, 2023
  10. Junio C HamanoDec 20, 2023
  11. 0/8 reftable: fixes and optimizations (pt.2)Patrick Steinhardt, Dec 28, 2023
  12. 1/8 reftable/stack: do not overwrite errors when compactingPatrick Steinhardt, Dec 28, 2023
  13. 2/8 reftable/stack: do not auto-compact twice in `reftable_stack_add()`Patrick Steinhardt, Dec 28, 2023
  14. 3/8 reftable/writer: fix index corruption when writing multiple indicesPatrick Steinhardt, Dec 28, 2023
  15. 4/8 reftable/record: constify some parts of the interfacePatrick Steinhardt, Dec 28, 2023
  16. 5/8 reftable/record: store "val1" hashes as static arraysPatrick Steinhardt, Dec 28, 2023
  17. Junio C HamanoDec 28, 2023
  18. 6/8 reftable/record: store "val2" hashes as static arraysPatrick Steinhardt, Dec 28, 2023
  19. 7/8 reftable/merged: really reuse buffers to compute record keysPatrick Steinhardt, Dec 28, 2023
  20. Junio C HamanoDec 28, 2023
  21. 8/8 reftable/merged: transfer ownership of records when iteratingPatrick Steinhardt, Dec 28, 2023
  22. Junio C HamanoDec 28, 2023
  23. 0/8 reftable: fixes and optimizations (pt.2)Patrick Steinhardt, Jan 3, 2024
  24. 1/8 reftable/stack: do not overwrite errors when compactingPatrick Steinhardt, Jan 3, 2024
  25. Han-Wen NienhuysFeb 14, 2024
  26. Patrick SteinhardtFeb 15, 2024
  27. 2/8 reftable/stack: do not auto-compact twice in `reftable_stack_add()`Patrick Steinhardt, Jan 3, 2024
  28. 3/8 reftable/writer: fix index corruption when writing multiple indicesPatrick Steinhardt, Jan 3, 2024
  29. 4/8 reftable/record: constify some parts of the interfacePatrick Steinhardt, Jan 3, 2024
  30. 5/8 reftable/record: store "val1" hashes as static arraysPatrick Steinhardt, Jan 3, 2024
  31. Karthik NayakFeb 5, 2024
  32. Patrick SteinhardtFeb 6, 2024
  33. 6/8 reftable/record: store "val2" hashes as static arraysPatrick Steinhardt, Jan 3, 2024
  34. 7/8 reftable/merged: really reuse buffers to compute record keysPatrick Steinhardt, Jan 3, 2024
  35. 8/8 reftable/merged: transfer ownership of records when iteratingPatrick Steinhardt, Jan 3, 2024
  36. Karthik NayakFeb 5, 2024

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.