diff options
author | Indrajith K L | 2022-12-03 17:00:20 +0530 |
---|---|---|
committer | Indrajith K L | 2022-12-03 17:00:20 +0530 |
commit | f5c4671bfbad96bf346bd7e9a21fc4317b4959df (patch) | |
tree | 2764fc62da58f2ba8da7ed341643fc359873142f /v_windows/v/cmd/tools/fast | |
download | cli-tools-windows-f5c4671bfbad96bf346bd7e9a21fc4317b4959df.tar.gz cli-tools-windows-f5c4671bfbad96bf346bd7e9a21fc4317b4959df.tar.bz2 cli-tools-windows-f5c4671bfbad96bf346bd7e9a21fc4317b4959df.zip |
Diffstat (limited to 'v_windows/v/cmd/tools/fast')
-rw-r--r-- | v_windows/v/cmd/tools/fast/.gitignore | 5 | ||||
-rw-r--r-- | v_windows/v/cmd/tools/fast/fast.v | 200 | ||||
-rw-r--r-- | v_windows/v/cmd/tools/fast/fast_job.v | 37 | ||||
-rw-r--r-- | v_windows/v/cmd/tools/fast/fast_main.js | 67 | ||||
-rw-r--r-- | v_windows/v/cmd/tools/fast/footer.html | 4 | ||||
-rw-r--r-- | v_windows/v/cmd/tools/fast/header.html | 65 |
6 files changed, 378 insertions, 0 deletions
diff --git a/v_windows/v/cmd/tools/fast/.gitignore b/v_windows/v/cmd/tools/fast/.gitignore new file mode 100644 index 0000000..1efae28 --- /dev/null +++ b/v_windows/v/cmd/tools/fast/.gitignore @@ -0,0 +1,5 @@ +fast +index.html +table.html +v.c +v2 diff --git a/v_windows/v/cmd/tools/fast/fast.v b/v_windows/v/cmd/tools/fast/fast.v new file mode 100644 index 0000000..3b0b282 --- /dev/null +++ b/v_windows/v/cmd/tools/fast/fast.v @@ -0,0 +1,200 @@ +// Copyright (c) 2019-2021 Alexander Medvednikov. All rights reserved. +// Use of this source code is governed by an MIT license +// that can be found in the LICENSE file. +import os +import time + +// TODO -usecache +const voptions = ' -skip-unused -show-timings -stats ' + +const exe = os.executable() + +const fast_dir = os.dir(exe) + +const vdir = @VEXEROOT + +fn main() { + dump(fast_dir) + dump(vdir) + os.chdir(fast_dir) ? + if !os.exists('$vdir/v') && !os.is_dir('$vdir/vlib') { + println('fast.html generator needs to be located in `v/cmd/tools/fast`') + } + println('fast.html generator\n') + println('Fetching updates...') + ret := os.system('$vdir/v up') + if ret != 0 { + println('failed to update V') + return + } + // Fetch the last commit's hash + commit := exec('git rev-parse HEAD')[..8] + if !os.exists('table.html') { + os.create('table.html') ? + } + mut table := os.read_file('table.html') ? + if os.exists('website/index.html') { + uploaded_index := os.read_file('website/index.html') ? + if uploaded_index.contains('>$commit<') { + println('nothing to benchmark') + exit(1) + return + } + } + // for i, commit in commits { + message := exec('git log --pretty=format:"%s" -n1 $commit') + // println('\n${i + 1}/$commits.len Benchmarking commit $commit "$message"') + println('\nBenchmarking commit $commit "$message"') + // Build an optimized V + // println('Checking out ${commit}...') + // exec('git checkout $commit') + println(' Building vprod...') + os.chdir(vdir) ? + if os.args.contains('-noprod') { + exec('./v -o vprod cmd/v') // for faster debugging + } else { + exec('./v -o vprod -prod -prealloc cmd/v') + } + // println('cur vdir="$vdir"') + // cache vlib modules + exec('$vdir/v wipe-cache') + exec('$vdir/v -o v2 -prod cmd/v') + // measure + diff1 := measure('$vdir/vprod $voptions -o v.c cmd/v', 'v.c') + mut tcc_path := 'tcc' + $if freebsd { + tcc_path = '/usr/local/bin/tcc' + if vdir.contains('/tmp/cirrus-ci-build') { + tcc_path = 'clang' + } + } + if os.args.contains('-clang') { + tcc_path = 'clang' + } + diff2 := measure('$vdir/vprod $voptions -cc $tcc_path -o v2 cmd/v', 'v2') + diff3 := 0 // measure('$vdir/vprod -native $vdir/cmd/tools/1mil.v', 'native 1mil') + diff4 := measure('$vdir/vprod -usecache $voptions -cc clang examples/hello_world.v', + 'hello.v') + vc_size := os.file_size('v.c') / 1000 + // scan/parse/check/cgen + scan, parse, check, cgen, vlines := measure_steps(vdir) + // println('Building V took ${diff}ms') + commit_date := exec('git log -n1 --pretty="format:%at" $commit') + date := time.unix(commit_date.int()) + // + os.chdir(fast_dir) ? + mut out := os.create('table.html') ? + // Place the new row on top + html_message := message.replace_each(['<', '<', '>', '>']) + table = + '<tr> + <td>$date.format()</td> + <td><a target=_blank href="https://github.com/vlang/v/commit/$commit">$commit</a></td> + <td>$html_message</td> + <td>${diff1}ms</td> + <td>${diff2}ms</td> + <td>${diff3}ms</td> + <td>${diff4}ms</td> + <td>$vc_size KB</td> + <td>${parse}ms</td> + <td>${check}ms</td> + <td>${cgen}ms</td> + <td>${scan}ms</td> + <td>$vlines</td> + <td>${int(f64(vlines) / f64(diff1) * 1000.0)}</td> + </tr>\n' + + table.trim_space() + out.writeln(table) ? + out.close() + // Regenerate index.html + header := os.read_file('header.html') ? + footer := os.read_file('footer.html') ? + mut res := os.create('index.html') ? + res.writeln(header) ? + res.writeln(table) ? + res.writeln(footer) ? + res.close() + //} + // exec('git checkout master') + // os.write_file('last_commit.txt', commits[commits.len - 1]) ? + // Upload the result to github pages + if os.args.contains('-upload') { + println('uploading...') + os.chdir('website') ? + os.execute_or_exit('git checkout gh-pages') + os.cp('../index.html', 'index.html') ? + os.rm('../index.html') ? + os.system('git commit -am "update benchmark"') + os.system('git push origin gh-pages') + } +} + +fn exec(s string) string { + e := os.execute_or_exit(s) + return e.output.trim_right('\r\n') +} + +// returns milliseconds +fn measure(cmd string, description string) int { + println(' Measuring $description') + println(' Warming up...') + println(cmd) + for _ in 0 .. 3 { + exec(cmd) + } + println(' Building...') + mut runs := []int{} + for r in 0 .. 5 { + println(' Sample ${r + 1}/5') + sw := time.new_stopwatch() + exec(cmd) + runs << int(sw.elapsed().milliseconds()) + } + // discard lowest and highest time + runs.sort() + runs = runs[1..4] + mut sum := 0 + for run in runs { + sum += run + } + return int(sum / 3) +} + +fn measure_steps(vdir string) (int, int, int, int, int) { + resp := os.execute_or_exit('$vdir/vprod $voptions -o v.c cmd/v') + + mut scan, mut parse, mut check, mut cgen, mut vlines := 0, 0, 0, 0, 0 + lines := resp.output.split_into_lines() + if lines.len == 3 { + parse = lines[0].before('.').int() + check = lines[1].before('.').int() + cgen = lines[2].before('.').int() + } else { + ms_lines := lines.map(it.split(' ms ')) + for line in ms_lines { + if line.len == 2 { + if line[1] == 'SCAN' { + scan = line[0].int() + } + if line[1] == 'PARSE' { + parse = line[0].int() + } + if line[1] == 'CHECK' { + check = line[0].int() + } + if line[1] == 'C GEN' { + cgen = line[0].int() + } + } else { + // Fetch number of V lines + if line[0].contains('V') && line[0].contains('source') && line[0].contains('size') { + start := line[0].index(':') or { 0 } + end := line[0].index('lines,') or { 0 } + s := line[0][start + 1..end] + vlines = s.trim_space().int() + } + } + } + } + return scan, parse, check, cgen, vlines +} diff --git a/v_windows/v/cmd/tools/fast/fast_job.v b/v_windows/v/cmd/tools/fast/fast_job.v new file mode 100644 index 0000000..e03988a --- /dev/null +++ b/v_windows/v/cmd/tools/fast/fast_job.v @@ -0,0 +1,37 @@ +// Copyright (c) 2019-2021 Alexander Medvednikov. All rights reserved. +// Use of this source code is governed by an MIT license +// that can be found in the LICENSE file. +import os +import time + +// A job that runs in the background, checks for repo updates, +// runs fast.v, pushes the HTML result to the fast.vlang.io GH pages repo. +fn main() { + println(time.now()) + if !os.exists('website') { + println('cloning the website repo...') + os.system('git clone git@github.com:/vlang/website.git') + } + if !os.exists('fast') { + println('"fast" binary (built with `v fast.v`) was not found') + return + } + for { + res_pull := os.execute('git pull --rebase') + if res_pull.exit_code != 0 { + println('failed to git pull. uncommitted changes?') + return + } + // println('running ./fast') + resp := os.execute('./fast -upload') + if resp.exit_code < 0 { + println(resp.output) + return + } + if resp.exit_code != 0 { + println('resp != 0, skipping') + println(resp.output) + } + time.sleep(180 * time.second) + } +} diff --git a/v_windows/v/cmd/tools/fast/fast_main.js b/v_windows/v/cmd/tools/fast/fast_main.js new file mode 100644 index 0000000..d6b2d19 --- /dev/null +++ b/v_windows/v/cmd/tools/fast/fast_main.js @@ -0,0 +1,67 @@ +const delta = 18; + +(function () { + var table = document.querySelector("table"); + var isTbody = table.children[0].nodeName == "TBODY"; + var trs = isTbody + ? table.children[0].querySelectorAll("tr") + : table.querySelectorAll("tr"); + trs.forEach(function (tr, idx) { + if (idx != 0 && idx + 1 < trs.length) { + var vc = 3, vv = 4, vf = 5, vh = 6; + var textContent = { + vc: tr.children[vc].textContent, + vv: tr.children[vv].textContent, + vf: tr.children[vf].textContent, + vh: tr.children[vh].textContent + }; + var currentData = { + vc: int(textContent.vc.slice(0, -2)), + vv: int(textContent.vv.slice(0, -2)), + vf: int(textContent.vf.slice(0, -2)), + vh: int(textContent.vh.slice(0, -2)) + }; + var prevData = { + vc: int(trs[idx + 1].children[vc].textContent.slice(0, -2)), + vv: int(trs[idx + 1].children[vv].textContent.slice(0, -2)), + vf: int(trs[idx + 1].children[vf].textContent.slice(0, -2)), + vh: int(trs[idx + 1].children[vh].textContent.slice(0, -2)) + }; + var result = { + vc: currentData.vc - prevData.vc, + vv: currentData.vv - prevData.vv, + vf: currentData.vf - prevData.vf, + vh: currentData.vh - prevData.vh + }; + if (Math.abs(result.vc) > delta) + tr.children[vc].appendChild(createElement(result.vc)); + if (Math.abs(result.vv) > delta * 2) + tr.children[vv].appendChild(createElement(result.vv)); + if (Math.abs(result.vf) > delta * 2) + tr.children[vf].appendChild(createElement(result.vf)); + if (Math.abs(result.vh) > delta * 2) + tr.children[vh].appendChild(createElement(result.vh)); + } + }); + function int(src) { + return src - 0; + } + function getClassName(x) { + if (x == 0) + return "equal"; + return x < 0 ? "plus" : "minus"; + } + function createElement(result) { + var el = document.createElement("span"); + var parsedResult = parseResult(result); + el.classList.add("diff"); + el.classList.add(getClassName(result)); + el.textContent = parsedResult; + return el; + } + function parseResult(x) { + if (x == 0) + return "0"; + return x > 0 ? "+" + x : x; + } +})(); diff --git a/v_windows/v/cmd/tools/fast/footer.html b/v_windows/v/cmd/tools/fast/footer.html new file mode 100644 index 0000000..37f5c0f --- /dev/null +++ b/v_windows/v/cmd/tools/fast/footer.html @@ -0,0 +1,4 @@ +</table> +<script src="main.js"></script> +</body> +</html> diff --git a/v_windows/v/cmd/tools/fast/header.html b/v_windows/v/cmd/tools/fast/header.html new file mode 100644 index 0000000..8f4ee5c --- /dev/null +++ b/v_windows/v/cmd/tools/fast/header.html @@ -0,0 +1,65 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="UTF-8"> +<meta name="viewport" content="width=device-width, initial-scale=1"> +<title>Is V still fast?</title> +<style> +*, body { + font-family: Menlo, Monospace, 'Courier New'; +} +table { + width: 1800px; +} +table, td { + border-collapse: collapse; + border: 1px solid #dfdfdf; +} +td { + padding: 5px; + position: relative; +} +.diff { + border-radius: 2.5px; + color: #ffffff; + padding: 0 5px 0 5px; + position: absolute; + right: 5px; +} +.minus { + background-color: rgb(195, 74, 104); +} +.plus { + background-color: #8BC34A; +} +.equal { + background-color: rgb(113, 68, 172); +} +</style> +</head> +<body> +<h2>Is V still fast?</h2> + +Monitoring compilation speed for each commit. <br><br> +Running on a free tier AWS t2.micro instance (1 vCPU). Typical desktop hardware is 2-3 times faster. <br><br> +Source code: <a target=blank href='https://github.com/vlang/v/blob/master/cmd/tools/fast/fast.v'>fast.v</a> <br><br> + + + +<table> + <tr> + <td style='width:180px'>timestamp</td> + <td style='width:85px'>commit</td> + <td>commit message</td> + <td style='width:120px'>v -o v.c</td> + <td style='width:120px'>v -o v</td> + <td style='width:130px'>v -native 1mil.v</td> + <td style='width:120px'>v hello.v</td> + <td style='width:85px'>v.c size</td> + <td style='width:55px'>parse</td> + <td style='width:55px'>check</td> + <td style='width:55px'>cgen</td> + <td style='width:55px'>scan</td> + <td style='width:80px'>V lines</td> + <td style='width:95px'>V lines/s</td> + </tr> |