tools/performance_compare: speed it up and make it more robust

* tools/performance_compare is now more robust. It uses the C source from the time of the v commit, instead of always the latest one. It also now clones https://github.com/vlang/vc just once per comparison, not for every build.

* Remove obsoleted tools/compare_v_performance_between_commits shell script.
pull/2229/head
Delyan Angelov 2019-10-04 16:11:29 +03:00 committed by Alexander Medvednikov
parent d2c5b6d964
commit f43c4fd81c
2 changed files with 71 additions and 123 deletions

View File

@ -1,98 +0,0 @@
#!/bin/sh
set -e
msg() {
printf '%s\n' "$*";
}
if [ $# -ne 2 ]; then
msg "Usage: compare_v_to_c_performance COMMIT_BEFORE COMMIT_AFTER"
exit 1
fi
depend_on() {
type "$1" >/dev/null 2>&1 || {
printf 'ERR: missing tool "%s"\n' "$1" >&2; exit 1;
}
}
depend_on sh
depend_on cp
depend_on rm
depend_on wc
depend_on head
depend_on cc
depend_on strip
depend_on git
depend_on upx
depend_on make
depend_on hyperfine
######################################################################
## NB: cc should be a working, recent, sane C99 compiler
## cc is used by the Makefile to bootstrap v (both gcc/clang work)
##
## If you are a C/V developer in a unix environment, you most probably
## already have the above installed, with the possible exception of:
## https://github.com/sharkdp/hyperfine
##
## Installing them is out of scope of this tool.
######################################################################
COMMIT_B="$1"
COMMIT_A="$2"
CWD="$(pwd)"
WORKDIR="/tmp"
B="$WORKDIR/v_at_$COMMIT_B"
A="$WORKDIR/v_at_$COMMIT_A"
prepare_v() {
msg
msg "Cloning current v source to $1 ..."
git clone --quiet "$CWD" "$1"
cd "$1"
git checkout --quiet "$2"
msg "Making v and vprod compilers in $1"
make > /dev/null
./v -o v compiler
./v -prod -o vprod compiler
cp v v_stripped
cp vprod vprod_stripped
strip *_stripped
cp v_stripped v_stripped_upxed
cp vprod_stripped vprod_stripped_upxed
upx -qqq --lzma v_stripped_upxed
upx -qqq --lzma vprod_stripped_upxed
wc -c "$1/v" "$1/v_stripped" "$1/v_stripped_upxed" "$1/vprod" "$1/vprod_stripped" "$1/vprod_stripped_upxed" | head -n -1
VVERSION="$($1/v --version)"
GVERSION="$(git rev-parse --short --verify HEAD)"
msg "V version is: $VVERSION , local source commit: $GVERSION"
}
compare_v_performance() {
CMD="$1"
msg "---------------------------------------------------------------------------------"
msg "Compare '$CMD'"
hyperfine --warmup=3 "cd '$B/' && $CMD " "cd '$A/' && $CMD "
msg
}
##############################################################################
# Cleanup artifacts from previous runs of this tool:
cd "$WORKDIR"
rm -rf "$A/" "$B/"
##############################################################################
msg "Comparing v compiler performance of commit $COMMIT_B (before) vs commit $COMMIT_A (after) ..."
prepare_v "$B" "$COMMIT_B"
prepare_v "$A" "$COMMIT_A"
cd "$WORKDIR"
compare_v_performance "./v -o x.c compiler"
compare_v_performance "./vprod -o x.c compiler"
compare_v_performance "./vprod -o x compiler"

View File

@ -16,6 +16,7 @@ mut:
workdir string // the working folder (typically /tmp), where the tool will write workdir string // the working folder (typically /tmp), where the tool will write
a string // the full path to the 'after' folder inside workdir a string // the full path to the 'after' folder inside workdir
b string // the full path to the 'before' folder inside workdir b string // the full path to the 'before' folder inside workdir
vc string // the full path to the vc folder inside workdir. It is used during bootstrapping v from the C source.
commit_before string // the git commit for the 'before' state commit_before string // the git commit for the 'before' state
commit_after string // the git commit for the 'after' state commit_after string // the git commit for the 'after' state
} }
@ -54,7 +55,9 @@ fn (c Context) compare_versions() {
// Input is validated at this point... // Input is validated at this point...
//Cleanup artifacts from previous runs of this tool: //Cleanup artifacts from previous runs of this tool:
os.chdir( c.workdir ) os.chdir( c.workdir )
run('rm -rf "$c.a" "$c.b" ') run('rm -rf "$c.a" "$c.b" "$c.vc" ')
// clone the VC source *just once per comparison*, and reuse it:
run('git clone --quiet https://github.com/vlang/vc \'$c.vc\' ')
println('Comparing v compiler performance of commit $c.commit_before (before) vs commit $c.commit_after (after) ...') println('Comparing v compiler performance of commit $c.commit_before (before) vs commit $c.commit_after (after) ...')
c.prepare_v( c.b , c.commit_before ) c.prepare_v( c.b , c.commit_before )
@ -73,24 +76,66 @@ fn show_sizes_of_files(files []string) {
} }
} }
fn line_to_timestamp_and_commit(line string) (int, string) {
parts := line.split(' ')
return parts[0].int(), parts[1]
}
fn (c &Context) prepare_vc_source( cdir string, commit string ) {
os.chdir( cdir )
// Building a historic v with the latest vc is not always possible ...
// It is more likely, that the vc *at the time of the v commit*,
// or slightly before that time will be able to build the historic v:
vline := run('git rev-list -n1 --timestamp \'$commit\' ')
v_timestamp, _ := line_to_timestamp_and_commit( vline )
os.chdir( c.vc )
run('git checkout master')
vcbefore := run('git rev-list HEAD -n1 --timestamp --before=$v_timestamp ')
_, vccommit_before := line_to_timestamp_and_commit( vcbefore )
run('git checkout \'$vccommit_before\' ')
os.chdir( cdir )
}
fn (c &Context) prepare_v( cdir string, commit string ) { fn (c &Context) prepare_v( cdir string, commit string ) {
mut cc := os.getenv('CC')
if cc == '' { cc = 'cc' }
mut command_for_building_v_from_c_source := '$cc -std=gnu11 -w -o cv $c.vc/v.c -lm'
if 'windows' == os.user_os() {
command_for_building_v_from_c_source = '$cc -std=gnu11 -w -o cv.exe $c.vc/v_win.c'
}
println('') println('')
// prepare c.vc first
os.chdir( c.vc )
run('git checkout master')
println('Cloning current v source to $cdir ...') println('Cloning current v source to $cdir ...')
os.system('git clone --quiet \'$c.cwd\' \'$cdir\' ') os.system('git clone --quiet \'$c.cwd\' \'$cdir\' ')
os.chdir( cdir ) os.chdir( cdir )
os.system('git checkout --quiet \'$commit\' ') os.system('git checkout --quiet \'$commit\' ')
run('git clean -f')
c.prepare_vc_source( cdir, commit )
println('Making v and vprod compilers in $cdir') println('Making v and vprod compilers in $cdir')
run('make') run(command_for_building_v_from_c_source)
run('./v -o v compiler/ ') run('./cv -o v compiler/ ')
run('./v -prod -o vprod compiler/ ') run('./cv -prod -o vprod compiler/ ')
run('cp cv cv_stripped')
run('cp v v_stripped') run('cp v v_stripped')
run('cp vprod vprod_stripped') run('cp vprod vprod_stripped')
run('strip *_stripped') run('strip *_stripped')
run('cp cv_stripped cv_stripped_upxed')
run('cp v_stripped v_stripped_upxed') run('cp v_stripped v_stripped_upxed')
run('cp vprod_stripped vprod_stripped_upxed') run('cp vprod_stripped vprod_stripped_upxed')
run('upx -qqq --lzma cv_stripped_upxed')
run('upx -qqq --lzma v_stripped_upxed') run('upx -qqq --lzma v_stripped_upxed')
run('upx -qqq --lzma vprod_stripped_upxed') run('upx -qqq --lzma vprod_stripped_upxed')
show_sizes_of_files(["$cdir/cv", "$cdir/cv_stripped", "$cdir/cv_stripped_upxed"])
show_sizes_of_files(["$cdir/v", "$cdir/v_stripped", "$cdir/v_stripped_upxed"]) show_sizes_of_files(["$cdir/v", "$cdir/v_stripped", "$cdir/v_stripped_upxed"])
show_sizes_of_files(["$cdir/vprod", "$cdir/vprod_stripped", "$cdir/vprod_stripped_upxed"]) show_sizes_of_files(["$cdir/vprod", "$cdir/vprod_stripped", "$cdir/vprod_stripped_upxed"])
println("V version is: " + run("$cdir/v --version") + " , local source commit: " + run("git rev-parse --short --verify HEAD") ) println("V version is: " + run("$cdir/v --version") + " , local source commit: " + run("git rev-parse --short --verify HEAD") )
@ -148,6 +193,7 @@ fn main(){
context.b = context.normalized_workpath_for_commit( context.commit_before ) context.b = context.normalized_workpath_for_commit( context.commit_before )
context.a = context.normalized_workpath_for_commit( context.commit_after ) context.a = context.normalized_workpath_for_commit( context.commit_after )
context.vc = context.normalized_workpath_for_commit( 'vc' )
if !os.is_dir( context.workdir ) { if !os.is_dir( context.workdir ) {
msg := 'Work folder: ' + context.workdir + ' , does not exist.' msg := 'Work folder: ' + context.workdir + ' , does not exist.'