You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I'm filing an issue just the check whether it would be a valid feature and reasonable to implement on BenchmarkDotNet's side. I've built a small and ugly helper that produces difference between two BenchmarkDotNet runs using CSV reports: https://github.com/lahma/BenchmarkDotNet.ResultDiff .
So the parsing is ugly and brittle, but having a feature that would clearly state difference between various runs in percentages/absolute values seems beneficial to me. I've used when optimizing the Jint library and I feel it's great way to easily communicate the difference. I see people throwing two sets of results (before/after) when creating optimization PRs and if there are more than 3 rows to mentally diff, it gets burdensome (or it's just me).
So what I would suggest is some form of exporter that keeps track of every run done in efficient raw data format, say normal_file_name_yyyy-MM-dd-HH-mm-ss.data and then runs a diff of oldest and newest (by default) and produces similar output like the tool I linked which shows what's the actual difference between work done.
Implementing it into the existing BenchmarkDotNet.Tool project with the sub-commands concept.
The subcommand run would execute benchmarks: dotnet benchmarkdotnet run [arguments] [options]
The subcommand diff would get the difference between a baseline report and another report: dotnet benchmarkdotnet diff [arguments] [options]
This design is similiar to other well known dotnet tools (e.g. tooling for EF Core).
In the following example database is a sub-command of the ef command: dotnet ef database [arguments]
Advantages
One single tool to install
All (sub)-commands are compatible with a specific BenchmarkDotNet version
I think it's a good idea to reuse BenchmarkDotNet.Tool for all kinds of commands. We don't need many different NuGet packages for different commands.
If we want to have another kind of the summary table, we should have a corresponding exporter which allows getting this new "diff" table for the current benchmarking session.
Currently, we don't have a proper serialization format for benchmark results (see Summary Save/Load/Combine #305). I have some design notes for this format, but I still didn't come with good specifications for that. I think that the best way is to finish these specifications and introduce commands for post-processing. In this case, we will be able to apply any kinds of exporters to benchmark session which are already finished. Also, we can introduce a special kind of exporters which can consume two different reports (we can call it Differ).
The current CSV export format is a temporary hack which I needed for the RPlotExporter. It wasn't designed for other kinds of post-processing (e.g., it doesn't include the environment data: we can't form a proper header for the diff summary table automatically).
I love all the possibilities listed here. I'd also like to point out the case which is important to me. I usually have baseline run that tests system (multiple methods, sub-systems) and I try to see how the results have been affetected by change. So in my case it's more of a "overall rps/s change after I fine-tuned data-structures allocation patterns" instead of "which of the two methods is faster". So I usually run multiple benchmarks stressing library from the top and check that no regressions are introduced when I tweak some particular case.
So in short I'll run same benchmarks and I usually want to see allocation and duration changes for the same benchmark over time.
I think it's a good idea to reuse BenchmarkDotNet.Tool for all kinds of commands. We don't need many different NuGet packages for different commands.
@AndreyAkinshin personally I would prefer a dedicated tool for every command. It would give us a better overview of what our users are using (nuget stats) and cleaner commands, more Unix-like?
Commands with a single tool:
dotnet benchmark run abc.dll
dotnet benchmark compare x.json y.json
Also in the future I would like to move some of our code to stand-alone tools. Examples: disassembler (could be reused by others) and profilers (could also be reused)
@AndreyAkinshin what do you think about this idea in general?
Speaking of the files, as of today every run overwrites the previous result. I think that we should change it (maybe include a time stamp in the file name or sth like that?). Also, prefer JSON over CSV. It's more "type safe" to me ;p
I think that option "install one package and get all of the command line out of the box" is better than forcing users to install a separate NuGet package for each command.
Also, I don't like this command line:
dotnet compare x.json y.json
It's OK for us to reserve the dotnet benchmark keyword because BenchmarkDotNet is the most popular benchmarking library. However, I don't want to reserve dotnet compare for comparing BenchmarkDotNet-specific files (the same for disassembler and `profiler). Maybe we can resolve it via arguments like this:
BTW if we switch to System.CommandLine (#1016) it should be easier to write a single global tool that handles everything we want (it was designed for global tools, including support of auto-complete for the argument names!)
Reacted by Andrey Akinshin, Wojciech Nagórski and Joe4evr
It would be nice to have additional metrics reported with each summary, such as being able to display the net increase or decrease in each benchmark's mean execution time (compared to the previous run).
For example, something like:
Method | Mean | Error | StdDev | Delta Mean |
------ |---------:|----------:|----------:|-----------:|
TestA | 1.617 ns | 0.0583 ns | 0.0924 ns | ▼ 0.143ns | Increase in performance
TestB | 1.383 ns | 0.0218 ns | 0.0204 ns | ▲ 0.522ns | Decrease in performance
TestC | 4.288 ns | 0.1344 ns | 0.0819 ns | n/a | No records to compare to
Adding on to that idea, being able to plot changes in performance over time (even if it meant opening a file in a third-party program) would also be awesome and help greatly with development.
Reacted by Donovan Edye, Nikita Danilov, Anatoliy Siryi, Raul Santos, Magnus Lindhe, Gioacchino Piazzolla, Anton Zlygostev and Jason Finch
I don't know if new comparer tool will be the same of BenchmarkDotNet.Tool but as I said could be useful:
specify for base/new folder or csv file and tool should picks up file or last run from folder, my use case is one fixed base but multiple new with updates and every test I want to compare only last run, now comparer crashes.
I was also looking for something like this. It would be wonderful if I could easily run BDN with a comparison CLI argument as part of a PR cycle, and have PR submissions report the net increase (or decrease) in performance.
One of the biggest pain points I'm finding with BDN so far is there's no convenient way of comparing a before and after. So far, what I'm having to do is write a MyClass and MyClass2 which are identical except the performance change I'm trying out. This is a pretty grim methodology. It would be really good if it could compare across git commits.
+1 for this.
Please let me know if anyone is taking this up.
If not I can take it up.
As this would be of huge benefit for many people trying to use this on CI/CD pipelines.
Activity
adamsitnik commentedon Jan 11, 2019
Hi @lahma
I like this idea and I have even implemented a similar tool in the dotnet/performance repo https://github.com/dotnet/performance/tree/master/src/tools/ResultsComparer
Maybe we should add it as a new, global tool similar to #1006 ?
@AndreyAkinshin what do you think about adding such command line tools to the BDN repo?
CodeTherapist commentedon Jan 12, 2019
@adamsitnik @adamsitnik
I would like to implement that as well.
Design suggestion
Implementing it into the existing
BenchmarkDotNet.Toolproject with thesub-commandsconcept.The subcommand
runwould execute benchmarks:dotnet benchmarkdotnet run [arguments] [options]The subcommand
diffwould get the difference between a baseline report and another report:dotnet benchmarkdotnet diff [arguments] [options]This design is similiar to other well known dotnet tools (e.g. tooling for
EF Core).In the following example
databaseis a sub-command of theefcommand:dotnet ef database [arguments]Advantages
How would you like that?
AndreyAkinshin commentedon Jan 13, 2019
BenchmarkDotNet.Toolfor all kinds of commands. We don't need many different NuGet packages for different commands.Differ).lahma commentedon Jan 13, 2019
I love all the possibilities listed here. I'd also like to point out the case which is important to me. I usually have baseline run that tests system (multiple methods, sub-systems) and I try to see how the results have been affetected by change. So in my case it's more of a "overall rps/s change after I fine-tuned data-structures allocation patterns" instead of "which of the two methods is faster". So I usually run multiple benchmarks stressing library from the top and check that no regressions are introduced when I tweak some particular case.
So in short I'll run same benchmarks and I usually want to see allocation and duration changes for the same benchmark over time.
adamsitnik commentedon Jan 13, 2019
@AndreyAkinshin personally I would prefer a dedicated tool for every command. It would give us a better overview of what our users are using (nuget stats) and cleaner commands, more Unix-like?
Commands with a single tool:
With dedicated tools:
Also in the future I would like to move some of our code to stand-alone tools. Examples: disassembler (could be reused by others) and profilers (could also be reused)
@AndreyAkinshin what do you think about this idea in general?
Speaking of the files, as of today every run overwrites the previous result. I think that we should change it (maybe include a time stamp in the file name or sth like that?). Also, prefer JSON over CSV. It's more "type safe" to me ;p
AndreyAkinshin commentedon Jan 13, 2019
I think that option "install one package and get all of the command line out of the box" is better than forcing users to install a separate NuGet package for each command.
Also, I don't like this command line:
It's OK for us to reserve the
dotnet benchmarkkeyword because BenchmarkDotNet is the most popular benchmarking library. However, I don't want to reservedotnet comparefor comparing BenchmarkDotNet-specific files (the same fordisassemblerand `profiler). Maybe we can resolve it via arguments like this:adamsitnik commentedon Jan 13, 2019
@AndreyAkinshin You are right.
BTW if we switch to System.CommandLine (#1016) it should be easier to write a single global tool that handles everything we want (it was designed for global tools, including support of auto-complete for the argument names!)
paule96 commentedon Jan 16, 2019
This would be super nice. Currently, I try to compare the results in azure devops put don't find a good way to do this.
Wildenhaus commentedon Jan 25, 2019
It would be nice to have additional metrics reported with each summary, such as being able to display the net increase or decrease in each benchmark's mean execution time (compared to the previous run).
For example, something like:
Adding on to that idea, being able to plot changes in performance over time (even if it meant opening a file in a third-party program) would also be awesome and help greatly with development.
MarcoRossignoli commentedon Feb 21, 2019
@adamsitnik ask to me to follow up here after dotnet/performance#314 (review)
I don't know if new comparer tool will be the same of
BenchmarkDotNet.Toolbut as I said could be useful:dominikjeske commentedon Apr 18, 2020
This feature looks promising - is there any progress on this?
svengeance commentedon Sep 25, 2020
I was also looking for something like this. It would be wonderful if I could easily run BDN with a comparison CLI argument as part of a PR cycle, and have PR submissions report the net increase (or decrease) in performance.
rymeskar commentedon Nov 25, 2020
@adamsitnik and @AndreyAkinshin is there any news around 'run history difference reporting / exporting'?
gioce90 commentedon Jun 1, 2022
Same question
lloydjatkinson commentedon Feb 26, 2024
One of the biggest pain points I'm finding with BDN so far is there's no convenient way of comparing a before and after. So far, what I'm having to do is write a
MyClassandMyClass2which are identical except the performance change I'm trying out. This is a pretty grim methodology. It would be really good if it could compare across git commits.Tarun047 commentedon Mar 10, 2024
+1 for this.
Please let me know if anyone is taking this up.
If not I can take it up.
As this would be of huge benefit for many people trying to use this on CI/CD pipelines.
AndreyAkinshin commentedon Mar 10, 2024
@Tarun047 I'm working on it right now. A huge refactoring is coming with a new serialization format + a lot of new features including various reports.
Enterprize1 commentedon Sep 6, 2024
@lloydjatkinson I had the same thought and created https://www.nuget.org/packages/Enterprize1.BenchmarkDotNet.GitCompare that allows running BenchmarkDotNet Jobs for different commits/branches (or just HEAD to see the difference the current changes make). Hope it works as good for you as it does for me.