perf: clear vfs audit_cache before each run
When generating a stream clone, we spend a large amount of time auditing path.
Before this changes, the first run was warming the vfs cache for the other
runs, leading to a large runtime difference and a "faulty" reported timing for
the operation.
We now clear this important cache between run to get a more realistic timing.
Below are some example of median time change when clearing these cases. The
maximum time for a run did not changed significantly.
### data-env-vars.name = mozilla-central-2018-08-01-zstd-sparse-revlog
# benchmark.name = hg.perf.exchange.stream.generate
# bin-env-vars.hg.flavor = default
# bin-env-vars.hg.py-re2-module = default
# benchmark.variants.version = latest
no-clearing: 17.289905
cache-clearing: 21.587965 (+24.86%, +4.30)
## data-env-vars.name = mozilla-central-2024-03-22-zstd-sparse-revlog
no-clearing: 32.670748
cache-clearing: 40.467095 (+23.86%, +7.80)
## data-env-vars.name = mozilla-try-2019-02-18-zstd-sparse-revlog
no-clearing: 37.838858
cache-clearing: 46.072749 (+21.76%, +8.23)
## data-env-vars.name = mozilla-unified-2024-03-22-zstd-sparse-revlog
no-clearing: 32.969395
cache-clearing: 39.646209 (+20.25%, +6.68)
In addition, this significantly reduce the timing difference between the
performance command, from the perf extensions and a `real `hg bundle` call
producing a stream bundle. Some significant differences remain especially on
the "mozilla-try" repositories, but they are now smaller.
Note that some of that difference will actually not be
attributable to the stream generation (like maybe phases or branch map
computation).
Below are some benchmarks done on a currently draft changeset fixing some
unrelated slowness in `hg bundle` (34a78972af409d1ff37c29e60f6ca811ad1a457d)
### data-env-vars.name = mozilla-central-2018-08-01-zstd-sparse-revlog
# bin-env-vars.hg.flavor = default
# bin-env-vars.hg.py-re2-module = default
hg.perf.exchange.stream.generate: 21.587965
hg.command.bundle: 24.301799 (+12.57%, +2.71)
## data-env-vars.name = mozilla-central-2024-03-22-zstd-sparse-revlog
hg.perf.exchange.stream.generate: 40.467095
hg.command.bundle: 44.831317 (+10.78%, +4.36)
## data-env-vars.name = mozilla-unified-2024-03-22-zstd-sparse-revlog
hg.perf.exchange.stream.generate: 39.646209
hg.command.bundle: 45.395258 (+14.50%, +5.75)
## data-env-vars.name = mozilla-try-2019-02-18-zstd-sparse-revlog
hg.perf.exchange.stream.generate: 46.072749
hg.command.bundle: 55.882608 (+21.29%, +9.81)
## data-env-vars.name = mozilla-try-2023-03-22-zlib-general-delta
hg.perf.exchange.stream.generate: 334.716708
hg.command.bundle: 377.856767 (+12.89%, +43.14)
## data-env-vars.name = mozilla-try-2023-03-22-zstd-sparse-revlog
hg.perf.exchange.stream.generate: 302.972301
hg.command.bundle: 326.098755 (+7.63%, +23.13)
#require cvs112 no-root
This feature requires use of builtin cvsps!
$ echo "[extensions]" >> $HGRCPATH
$ echo "convert = " >> $HGRCPATH
create cvs repository with one project
$ mkdir cvsrepo
$ cd cvsrepo
$ CVSROOT=`pwd`
$ export CVSROOT
$ CVS_OPTIONS=-f
$ export CVS_OPTIONS
$ cd ..
$ rmdir cvsrepo
$ cvscall()
> {
> cvs -f "$@"
> }
output of 'cvs ci' varies unpredictably, so just discard it
$ cvsci()
> {
> sleep 1
> cvs -f ci "$@" >/dev/null
> }
$ cvscall -d "$CVSROOT" init
$ mkdir cvsrepo/proj
$ cvscall -q co proj
create file1 on the trunk
$ cd proj
$ touch file1
$ cvscall -Q add file1
$ cvsci -m"add file1 on trunk" file1
create two branches
$ cvscall -q tag -b v1_0
T file1
$ cvscall -q tag -b v1_1
T file1
create file2 on branch v1_0
$ cvscall -Q up -rv1_0
$ touch file2
$ cvscall -Q add file2
$ cvsci -m"add file2" file2
create file3, file4 on branch v1_1
$ cvscall -Q up -rv1_1
$ touch file3
$ touch file4
$ cvscall -Q add file3 file4
$ cvsci -m"add file3, file4 on branch v1_1" file3 file4
merge file2 from v1_0 to v1_1
$ cvscall -Q up -jv1_0
$ cvsci -m"MERGE from v1_0: add file2"
cvs commit: Examining .
Step things up a notch: now we make the history really hairy, with
changes bouncing back and forth between trunk and v1_2 and merges
going both ways. (I.e., try to model the real world.)
create branch v1_2
$ cvscall -Q up -A
$ cvscall -q tag -b v1_2
T file1
create file5 on branch v1_2
$ cvscall -Q up -rv1_2
$ touch file5
$ cvs -Q add file5
$ cvsci -m"add file5 on v1_2"
cvs commit: Examining .
create file6 on trunk post-v1_2
$ cvscall -Q up -A
$ touch file6
$ cvscall -Q add file6
$ cvsci -m"add file6 on trunk post-v1_2"
cvs commit: Examining .
merge file5 from v1_2 to trunk
$ cvscall -Q up -A
$ cvscall -Q up -jv1_2 file5
$ cvsci -m"MERGE from v1_2: add file5"
cvs commit: Examining .
merge file6 from trunk to v1_2
$ cvscall -Q up -rv1_2
$ cvscall up -jHEAD file6
U file6
$ cvsci -m"MERGE from HEAD: add file6"
cvs commit: Examining .
cvs rlog output
$ cvscall -q rlog proj | grep -E '^(RCS file|revision)'
RCS file: $TESTTMP/cvsrepo/proj/file1,v
revision 1.1
RCS file: $TESTTMP/cvsrepo/proj/Attic/file2,v
revision 1.1
revision 1.1.4.2
revision 1.1.4.1
revision 1.1.2.1
RCS file: $TESTTMP/cvsrepo/proj/Attic/file3,v
revision 1.1
revision 1.1.2.1
RCS file: $TESTTMP/cvsrepo/proj/Attic/file4,v
revision 1.1
revision 1.1.2.1
RCS file: $TESTTMP/cvsrepo/proj/file5,v
revision 1.2
revision 1.1
revision 1.1.2.1
RCS file: $TESTTMP/cvsrepo/proj/file6,v
revision 1.1
revision 1.1.2.2
revision 1.1.2.1
convert to hg (#1)
$ cd ..
$ hg convert --datesort proj proj.hg
initializing destination proj.hg repository
connecting to $TESTTMP/cvsrepo
scanning source...
collecting CVS rlog
15 log entries
creating changesets
9 changeset entries
sorting...
converting...
8 add file1 on trunk
7 add file2
6 MERGE from v1_0: add file2
5 file file3 was initially added on branch v1_1.
4 add file3, file4 on branch v1_1
3 add file5 on v1_2
2 add file6 on trunk post-v1_2
1 MERGE from HEAD: add file6
0 MERGE from v1_2: add file5
hg log -G output (#1)
$ hg -R proj.hg log -G --template "{rev} {desc}\n"
o 8 MERGE from v1_2: add file5
|
| o 7 MERGE from HEAD: add file6
| |
o | 6 add file6 on trunk post-v1_2
| |
| o 5 add file5 on v1_2
| |
| | o 4 add file3, file4 on branch v1_1
| | |
o | | 3 file file3 was initially added on branch v1_1.
|/ /
| o 2 MERGE from v1_0: add file2
|/
| o 1 add file2
|/
o 0 add file1 on trunk
convert to hg (#2: with merge detection)
$ hg convert \
> --config convert.cvsps.mergefrom='"^MERGE from (\S+):"' \
> --datesort \
> proj proj.hg2
initializing destination proj.hg2 repository
connecting to $TESTTMP/cvsrepo
scanning source...
collecting CVS rlog
15 log entries
creating changesets
9 changeset entries
sorting...
converting...
8 add file1 on trunk
7 add file2
6 MERGE from v1_0: add file2
5 file file3 was initially added on branch v1_1.
4 add file3, file4 on branch v1_1
3 add file5 on v1_2
2 add file6 on trunk post-v1_2
1 MERGE from HEAD: add file6
0 MERGE from v1_2: add file5
hg log -G output (#2)
$ hg -R proj.hg2 log -G --template "{rev} {desc}\n"
o 8 MERGE from v1_2: add file5
|
| o 7 MERGE from HEAD: add file6
| |
o | 6 add file6 on trunk post-v1_2
| |
| o 5 add file5 on v1_2
| |
| | o 4 add file3, file4 on branch v1_1
| | |
o | | 3 file file3 was initially added on branch v1_1.
|/ /
| o 2 MERGE from v1_0: add file2
|/
| o 1 add file2
|/
o 0 add file1 on trunk