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

Re: [PATCH 2/2] for-each-ref: add --count-matches option

From
Jeff King <peff@peff.net>
Date
Jun 27, 2023, 19:59 UTC
Message-ID
<20230627195900.GC1280909@coredump.intra.peff.net>
In-Reply-To
<xmqqmt0khik5.fsf@gitster.g>
On Tue, Jun 27, 2023 at 11:22:02AM -0700, Junio C Hamano wrote:
Show 5 quoted lines
>    - populate_value() -> get_object() -> oid_object_info_extended() ->
>      grab_common_values() asks for ATOM_OBJECTTYPE that should be a
>      single xstrdup(), but oid_object_info_extended() needs to parse
>      the object, but .info.contentp ought to be NULL and we should
>      not be calling parse_object_buffer().

This is the atom that I expect to give most of the cost. We should definitely be computing that just with a pack lookup (and chasing deltas through the pack, though commits usually aren't deltas). But without that atom, I think we would not even mmap the idx or pack file at all.

The ref-filter code is also pretty keen to malloc() little strings. When we're measuring 5ms total runtimes and there's just not that much actual work to do, those little things start to matter more.

> So it might be worth looking into where the time is going (didn't
> Peff or somebody do that a few years ago, though?) when using the
> default format and optimize or special case the codepath,[...]
Running:
 perf record -g git for-each-ref --format='%(refname) %(objecttype)' >/dev/null
 perf script report flamegraph
in linux.git shows that we spend a lot of time faulting in .idx pages.

A lot of the time is attributed to ref_array_sort(), but I think that's a red herring. It lazy-loads the atom values, so that's where most of the work is happening (though I would have thought it would just do the refname atom, not all of them; but I guess it doesn't really matter since we'll eventually need them to print anyway). Commenting out the sort call just shows the same time spent in format_ref_array_item().

The patches you're thinking of are probably:
  https://lore.kernel.org/git/YTNpQ7Od1U%2F5i0R7@coredump.intra.peff.net/

which are mostly about micro-optimizing out those mallocs. They do still help a little in the '%(refname)' case, but not nearly as much as dropping '%(objecttype)' does.

(Using --format=x in theory drops out some mallocs, but I wasn't able to measure any actual speedup).

> [...]but the
> responses I have seen from two of you makes me suspect that the new
> option is not the best general approach.

Yeah, my feeling is that with the reduced format, eliminating the pipe/wc overhead is a pretty small improvement.

-Peff
Previous: Junio C HamanoNext: Phillip Wood
Message 7 of 12 in “[RFC] for-each-ref: add --count-matches mode”
  1. 0/2 [RFC] for-each-ref: add --count-matches modeDerrick Stolee via GitGitGadget, Jun 26, 2023
  2. 2/2 for-each-ref: add --count-matches optionDerrick Stolee via GitGitGadget, Jun 26, 2023
  3. Junio C HamanoJun 26, 2023
  4. Jeff KingJun 27, 2023
  5. Phillip WoodJun 27, 2023
  6. Junio C HamanoJun 27, 2023
  7. Jeff KingJun 27, 2023
  8. Phillip WoodJun 28, 2023
  9. Junio C HamanoJun 28, 2023
  10. René ScharfeJul 11, 2023
  11. Derrick StoleeJul 10, 2023
  12. 1/2 for-each-ref: extract ref output loopDerrick Stolee via GitGitGadget, Jun 26, 2023

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.