mirror of
https://github.com/vim/vim
synced 2025-07-16 01:01:58 +00: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/*.in \
|
||||
runtime/indent/testdir/*.ok \
|
||||
runtime/indent/testdir/tools/* \
|
||||
runtime/ftplugin/*.vim \
|
||||
runtime/ftplugin/logtalk.dict \
|
||||
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