jj/cli/testing/bench-revsets-git.txt
Scott Taylor c5b0b0b68f revset: insert HeadsRange in Ancestors for nested range/filter
This allows evaluating ancestors/ranges involving filters significantly
faster. For instance, naively evaluating `::mine()` requires reading
every commit in the repo to check `mine()` on each commit, then finding
the ancestors of that set. This optimization rewrites `::mine()` to
`::heads(mine())`, since `heads(mine())` can be evaluated more
efficiently by only reading commits until the first successful match.

If someone is unaware of how revsets are implemented, this case can come
up pretty easily, such as by including `~mine()` in `immutable_heads()`
to make other people's commits immutable. In my local `jj` repo, this
optimization reduces the runtime of `jj log` with `~mine()` in
`immutable_heads()` from about 800ms down to about 50ms.

Benchmark results on Git repo:

```
::(v1.0.0..v2.40.0)     55.5% faster
author(peff)..          96.8% faster
```
2025-08-02 01:40:23 +00:00

78 lines
1.6 KiB
Text

# Revsets to pass to `jj bench revsets` on the Git repo
# Single tags
v1.0.0
v2.40.0
# Old history
::v1.0.0
..v1.0.0
# More history
::v2.40.0
..v2.40.0
# Only recent history
v2.39.0..v2.40.0
::v2.40.0 ~ ::v2.39.0
v2.39.0::v2.40.0
# Mostly recent history
v2.40.0-..
~(::v2.40.0)
# Tags and bookmarks
tags()
bookmarks()
# Local changes
(tags() | remote_bookmarks())..
# Intersection of range with a small subset
tags() & ::v2.40.0
v2.39.0 & ::v2.40.0
# Author and committer
author(peff)
committer(gitster)
# Intersection and union of large subsets
author(peff) & committer(gitster)
author(peff) | committer(gitster)
# Intersection of filter with a small subset
::v1.0.0 & (author(peff) & committer(gitster))
::v1.0.0 & (author(peff) | committer(gitster))
# Roots and heads of small subsets
roots(tags())
heads(tags())
# Roots and heads of large subsets
roots(author(peff))
heads(author(peff))
# Roots and heads of range
roots(::v2.40.0)
heads(::v2.40.0)
# Ancestors and ranges of large subsets
::(v1.0.0..v2.40.0)
author(peff)..
# Parents and ancestors of old commit
v1.0.0-
v1.0.0---
::v1.0.0---
# Children and descendants of old commit
v1.0.0+
v1.0.0+++
v1.0.0+++::
# Parents and ancestors of recent commit
v2.40.0-
v2.40.0---
::v2.40.0---
# Children and descendants of recent commit
v2.40.0+
v2.40.0+++
v2.40.0+++::
# Parents and ancestors of small subset
tags()-
tags()---
::tags()---
# Children and descendants of small subset
tags()+
tags()+++
tags()+++::
# Filter that doesn't read commit object
merges()
~merges()
# These are unbearably slow, so only filter within small set
files(root:"Makefile") & v1.0.0..v1.2.0
empty() & v1.0.0..v1.2.0
conflicts() & v1.0.0..v1.2.0