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, 07:30 UTC
Message-ID
<20230627073007.GD1226768@coredump.intra.peff.net>
In-Reply-To
<9121e027fb9f157878a9624ce6c834b69cd38472.1687792197.git.gitgitgadget@gmail.com>
On Mon, Jun 26, 2023 at 03:09:57PM +0000, Derrick Stolee via GitGitGadget wrote:
Show 10 quoted lines
> +for pattern in "refs/heads/" "refs/tags/" "refs/remotes"
> +do
> +	test_perf "count $pattern: git for-each-ref | wc -l" "
> +		git for-each-ref $pattern | wc -l
> +	"
> +
> +	test_perf "count $pattern: git for-each-ref --count-match" "
> +		git for-each-ref --count-matches $pattern
> +	"
> +done

I don't think this is a very realistic perf test, because for-each-ref is doing a bunch of work to generate its default format, only to have "wc" throw most of it away. Doing:

  git for-each-ref --format='%(refname)' | wc -l

is much better (obviously you have to remember to do that if you care about optimizing your command, but that's true of --count-matches, too).

Running hyperfine with three variants shows that the command above is competitive with --count-matches, though slightly slower (hyperfine complains about short commands and outliers because these runtimes are so tiny in the first place; I omitted those warnings from the output below for readability):

  Benchmark 1: ./git-for-each-ref refs/remotes/ | wc -l
    Time (mean ± σ):       6.1 ms ±   0.2 ms    [User: 3.0 ms, System: 3.6 ms]
    Range (min … max):     5.6 ms …   7.1 ms    397 runs
  
  Benchmark 2: ./git-for-each-ref --format="%(refname)" refs/remotes/ | wc -l
    Time (mean ± σ):       3.3 ms ±   0.2 ms    [User: 2.2 ms, System: 1.5 ms]
    Range (min … max):     3.0 ms …   4.0 ms    774 runs
  
  Benchmark 3: ./git-for-each-ref --count-matches refs/remotes/
    Time (mean ± σ):       2.4 ms ±   0.1 ms    [User: 1.5 ms, System: 0.9 ms]
    Range (min … max):     2.2 ms …   3.4 ms    1018 runs
  
  Summary
    './git-for-each-ref --count-matches refs/remotes/' ran
      1.33 ± 0.10 times faster than './git-for-each-ref --format="%(refname)" refs/remotes/ | wc -l'
      2.48 ± 0.17 times faster than './git-for-each-ref refs/remotes/ | wc -l'

I will note this is an unloaded multi-core system, which gives the piped version a slight edge. Total CPU is probably more interesting than wall-clock time, but all of these are so short that I think the results should be taken with a pretty big grain of salt (I had to switch from the "powersave" to "performance" CPU governor just to get more consistent results).

-Peff
Previous: Junio C HamanoNext: Phillip Wood
Message 4 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.