mirror of
https://github.com/vim/vim.git
synced 2025-09-23 03:43:49 -04:00
runtime(indent-tests): Instrument timed "search*()" calls
The offered "tracer.vim" script can be used to measure and record elapsed time for explicitly annotated "search*()"es, set off with "VIM_INDENT_TEST_TRACE_(START|END)" comment markers, in indent plugins. related: #17116 Signed-off-by: Aliaksei Budavei <0x000c70@gmail.com> Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
committed by
Christian Brabandt
parent
6924eb81f4
commit
fe8508eda0
1
Filelist
1
Filelist
@@ -863,6 +863,7 @@ RT_SCRIPTS = \
|
|||||||
runtime/indent/testdir/*.vim \
|
runtime/indent/testdir/*.vim \
|
||||||
runtime/indent/testdir/*.in \
|
runtime/indent/testdir/*.in \
|
||||||
runtime/indent/testdir/*.ok \
|
runtime/indent/testdir/*.ok \
|
||||||
|
runtime/indent/testdir/tools/* \
|
||||||
runtime/ftplugin/*.vim \
|
runtime/ftplugin/*.vim \
|
||||||
runtime/ftplugin/logtalk.dict \
|
runtime/ftplugin/logtalk.dict \
|
||||||
runtime/ftplugin/README.txt \
|
runtime/ftplugin/README.txt \
|
||||||
|
166
runtime/indent/testdir/tools/tracer.vim
Normal file
166
runtime/indent/testdir/tools/tracer.vim
Normal file
@@ -0,0 +1,166 @@
|
|||||||
|
vim9script
|
||||||
|
|
||||||
|
# Whenever indent plugins contain "search*()" lines explicitly annotated with
|
||||||
|
# "VIM_INDENT_TEST_TRACE_(START|END)" comment markers; this script can then be
|
||||||
|
# used as shown to measure and record elapsed time for such decorated calls.
|
||||||
|
#
|
||||||
|
# Usage:
|
||||||
|
# cd runtime/indent
|
||||||
|
# vim -u NONE -S testdir/tools/tracer.vim \
|
||||||
|
# html.vim javascript.vim \
|
||||||
|
# ../autoload/python.vim ../autoload/dist/vimindent.vim
|
||||||
|
# git diff
|
||||||
|
# make clean test
|
||||||
|
# vim testdir/00-TRACE_LOG.fail
|
||||||
|
|
||||||
|
def GenerateTempletForTracing(fname: string, vname: string): list<string>
|
||||||
|
#### ONLY INSTRUMENT "search*()"es FOR INDENT TESTS.
|
||||||
|
|
||||||
|
const templet: list<string> =<< trim eval END
|
||||||
|
|
||||||
|
if getcwd() =~# '\<runtime/indent$'
|
||||||
|
|
||||||
|
def! g:IndentTestTrace(id: string, start: list<number>, result: any): any
|
||||||
|
const end: list<number> = reltime(start)
|
||||||
|
|
||||||
|
if !has_key(g:indent_test_trace_times, id)
|
||||||
|
g:indent_test_trace_times[id] = []
|
||||||
|
endif
|
||||||
|
|
||||||
|
g:indent_test_trace_times[id]
|
||||||
|
->add(reltimefloat(end))
|
||||||
|
return result
|
||||||
|
enddef
|
||||||
|
|
||||||
|
def! g:IndentTestInitTracing()
|
||||||
|
# Possibly use a later "{fname}", cf. ":runtime indent/foo.vim".
|
||||||
|
autocmd_add([{{
|
||||||
|
replace: true,
|
||||||
|
group: 'tracing',
|
||||||
|
event: 'QuitPre',
|
||||||
|
bufnr: bufnr(),
|
||||||
|
cmd: 'g:IndentTestWriteTraceTimes()',
|
||||||
|
}}])
|
||||||
|
g:indent_test_trace_times = {{}}
|
||||||
|
enddef
|
||||||
|
|
||||||
|
def! g:IndentTestWriteTraceTimes()
|
||||||
|
# Anticipate usage by multiple languages.
|
||||||
|
const token: string = printf('%02x', (rand() % 26))
|
||||||
|
writefile(['" {fname}:',
|
||||||
|
"let {vname}_" .. token .. " = " .. string(g:indent_test_trace_times),
|
||||||
|
"let {vname}_" .. token .. "_summary = " .. string(g:indent_test_trace_times
|
||||||
|
->items()
|
||||||
|
->reduce((outer: dict<dict<any>>, times: list<any>) =>
|
||||||
|
extend({{[times[0]]: times[1]
|
||||||
|
->copy()
|
||||||
|
->reduce((inner: dict<any>, v: float) =>
|
||||||
|
extend({{
|
||||||
|
min: inner.min < v ? inner.min : v,
|
||||||
|
max: inner.max > v ? inner.max : v,
|
||||||
|
sum: (inner.sum + v),
|
||||||
|
avg: ((inner.sum + v) / inner.count),
|
||||||
|
}},
|
||||||
|
inner,
|
||||||
|
"keep"),
|
||||||
|
{{
|
||||||
|
min: v:numbermax - 0.0,
|
||||||
|
max: v:numbermin + 0.0,
|
||||||
|
sum: 0.0,
|
||||||
|
avg: 0.0,
|
||||||
|
count: len(times[1]),
|
||||||
|
}})}},
|
||||||
|
outer),
|
||||||
|
{{}}))],
|
||||||
|
(!empty($VIM_INDENT_TEST_LOG) && filewritable($VIM_INDENT_TEST_LOG))
|
||||||
|
? $VIM_INDENT_TEST_LOG
|
||||||
|
: "testdir/00-TRACE_LOG.fail",
|
||||||
|
"a")
|
||||||
|
enddef
|
||||||
|
|
||||||
|
call g:IndentTestInitTracing()
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
def! g:IndentTestTrace(_: string, _: list<number>, result: any): any
|
||||||
|
return result
|
||||||
|
enddef
|
||||||
|
|
||||||
|
endif
|
||||||
|
|
||||||
|
END
|
||||||
|
return templet
|
||||||
|
enddef
|
||||||
|
|
||||||
|
def InstrumentMarkedEntry(): bool
|
||||||
|
const marker_start: string = 'VIM_INDENT_TEST_TRACE_START'
|
||||||
|
const start: number = search('\C\<' .. marker_start .. '\>', 'ceW')
|
||||||
|
|
||||||
|
if start == 0
|
||||||
|
return false
|
||||||
|
endif
|
||||||
|
|
||||||
|
const marker_end: string = 'VIM_INDENT_TEST_TRACE_END'
|
||||||
|
const end: number = search('\C\<' .. marker_end .. '\>', 'ceW')
|
||||||
|
|
||||||
|
if end == 0
|
||||||
|
return false
|
||||||
|
endif
|
||||||
|
|
||||||
|
const tracee: list<string> = matchlist(
|
||||||
|
getline(start + 1),
|
||||||
|
'\(^.\+\)\(\<search\%(pair\)\=\%(pos\)\=\s*(.*$\)')
|
||||||
|
|
||||||
|
if empty(get(tracee, 1, '')) || empty(get(tracee, 2, ''))
|
||||||
|
return false
|
||||||
|
endif
|
||||||
|
|
||||||
|
const end_line: string = getline(end)
|
||||||
|
const tracer: string = printf('%sg:IndentTestTrace("%s", reltime(), %s',
|
||||||
|
tracee[1],
|
||||||
|
strpart(end_line, (stridx(end_line, marker_end) + strlen(marker_end) + 1)),
|
||||||
|
tracee[2])
|
||||||
|
|
||||||
|
if (end - start) > 1
|
||||||
|
setline((start + 1), tracer)
|
||||||
|
setline((end - 1), getline(end - 1) .. ')')
|
||||||
|
else
|
||||||
|
setline((start + 1), tracer .. ')')
|
||||||
|
endif
|
||||||
|
|
||||||
|
return true
|
||||||
|
enddef
|
||||||
|
|
||||||
|
def ProcessIndentPluginCmdlineArgs()
|
||||||
|
const names: list<string> = range(char2nr('a'), char2nr('z'))
|
||||||
|
->map((_: number, n: number) => nr2char(n, true))
|
||||||
|
var entries: number = 0
|
||||||
|
var next: number = 0
|
||||||
|
|
||||||
|
for fname: string in argv(-1)
|
||||||
|
if filereadable(fname) && filewritable(fname)
|
||||||
|
execute 'new ' .. fname
|
||||||
|
call cursor(1, 1)
|
||||||
|
|
||||||
|
while InstrumentMarkedEntry()
|
||||||
|
entries += 1
|
||||||
|
endwhile
|
||||||
|
|
||||||
|
if entries > 0
|
||||||
|
append(1, GenerateTempletForTracing(fname, get(names, next, names[-1])))
|
||||||
|
wq
|
||||||
|
endif
|
||||||
|
|
||||||
|
entries = 0
|
||||||
|
next += 1
|
||||||
|
endif
|
||||||
|
endfor
|
||||||
|
enddef
|
||||||
|
|
||||||
|
if empty(system('git status --porcelain=v1'))
|
||||||
|
ProcessIndentPluginCmdlineArgs()
|
||||||
|
endif
|
||||||
|
|
||||||
|
quitall
|
||||||
|
|
||||||
|
# vim:fdm=syntax:sw=2:ts=8:noet:nosta:
|
Reference in New Issue
Block a user