Key Values History File.
This python package come from a suit of software that aim to make your continious integration system able to compare intersting performance related metrics across commits.
You can also use this as an easy way to plot graphs.
- kvhfplot
- kvhfutils
The package expose python modules that you may find usefull:
- Modules to manipulate kvhf file ( kvhf.file and kvhf.stat )
- Wrapper simplifying gitpython interface to facilitate repository exploration(lib.gfe)
- Some convenients functions to open files even if parents directory does not exist (lib.ppath)
pip install --index-url https://test.pypi.org/simple/ kvhf
A KVHF file is composed from 3 kinds of entity, separated by lines
- Labels: Placed at the begining of the file prepended by # and separated by specified key_sep.
- Keys: Anything not starting by -, followed by key_sep, and somes values separated by precised val_sep
- Attributes : You can give the plotter more information about the last key which will change the way the plotter draw it. See the exemple in next section.
Imagine you have following file:
#t1,onlyforsearch:t2,t3
building time: 5, 6,7
-maxs: 6, 10, 11
-mins: 4, 5, 6
-stdevs: 1, 2, 3
-unity: sec
run time: 9,7,6
-mins: 4,5,4
Then the command
kvhfplot file
will output the plot this image:
If your selection match only one label, it switch to bar chart mode:
kvhfplot file -l t1
If you activate the comparison switch, it print to pie chart mode:
kvhfplot file -l t1 -c
Run kvhfplot -h to get more details about how to control what is being plotted (add title, choose keys...)
Any value can be "_", which denote the fact that for an iteration the value was unknown.
The plotter come with utilities to facilitate integration of KVHF continious integration systems, in order to plot metrics at wanted commits.
The recommended way to use kvhf in this purpose will be illustrated in following section. This will also serve as doc to use the package as a whole and wont expose every functionnalities of every tool. You are invited to read the help option of every executable.
The recommended way is to automatate of a kvhf file per commit, and to merge it with an accumulator. This way, in each commit, you have:
- A clean per commit resume file
- The accumulator to print the past
Without the accumulator, you are gonna need to extract a kvhf from the git history trought kvhfutils --git-extract (see later) to produce history plotting. But extracting is gonna be slower and slower for every commits.
First, you need a way to automate a per commit kvhf file creation. For this you can use:
- kvhfutils -k to add keys or attribute to allready existing kvhf file.
- kvhfutils -m to combine keys of two allready existing kvhf files.
- A third party software that produce kvhf files (https://github.com/crazyhouse33/eprof/)
- kvhfutils -v to check than the file is aligned and dont contain any kind of abnormalies that could come from a bug in you generation
According to your build system, create a script or a target that create that commit resume thanks to those tools. Lets call this generate.bash
ex:
kvhfutils per_commit_resume.kvf -k exe_size:$(du bin/myexe | cut -f1) -k exe_size:unity:Ko
kvhfutils per_commit_resume.kvf -v -k exec_time:$(TIMEFMT=%R; time the_perf_test >/dev/null) -k exec_time:unity:ms
In general you have to understand that changing labels coming from previous commits is going to be super annoying and dangerous (git rebase). And thus you must really be carefull with the choices of your labels.
This step is not mandatory to use kvhf but any humans are guaranted to make the following mistakes one day:
- Forgeting to rerun your first step script to overide the per_commit_resume file
- Forgeting to put a label on the new per_commit_resume file
- Forgeting to merge the resume with the accumulator
That's why you should integrate to your commits hooks the following actions.
(pre-commit) generate.bash
(pre-commit) kvhfutils --actualized per_commit_resume --required-length 1
This will check that the label of the file is existing and not the same as the previous commit one (Will ask you to input a label name if you did not do it in generate). This will also check than each key is of lenght 1
(pre-commit) kvhfutils -o accumulator.kvhf --historic-merge accumulator.kvhf per\_commit\_resume
This save the need to extract the whole history each time you want to plot it. This must be one of the last pre-commit action because if this is executed and a latter action fail, your hkvf file will be polluted with an additional erronous commit. However this error will be detected by the --required-lenght option
(post-commit) git commit --amend accumulator.kvhf per_commit_resume This may be unnecessary if your continuous integration already include your pre-commit modifications in the commit.
Choosing wich iteration to plot with the labels regexp selection/filter is not the only way. Alternatively you can use kvhfutils -g to extract a kvhf file from subsets of commits only. You are able to select commits that modified a particular set of file such as in the following exemple:
kvhfutils --git-extract --path-restrict src/executor.c -p io.c -o important_changes.kvhf
You can also specify a list of commits. The labels will be extracted in given order. You can achieve the same results as previous command with:
kvhfutils -g -c $(git rev-list src/executor.c io.c --reverse)
- Allow to execute a command in each commit before extraction. That would allow to generate kvhf files of previous commits with the current generation script. For now you should look into git rebase exec
- (plotting) Smarter way to choose the stale according to keys values
- (plotting) New attributes number of occurence, allong with total mode (that print summed value )
- (plotting)
- (utils) Allow -prefix option for merges that would append a prefix to any merged keys
- Add same keys option, that when recolting/plotting considers somes keys renamed (warning on collision)
- Undestand what'up with gfe tests not runnable out of my local machine (git submodule machinery messing with it, some necessary file are not versionned)