bdna 0.5.6

dotnet tool install --global bdna --version 0.5.6
                    
This package contains a .NET tool you can call from the shell/command line.
dotnet new tool-manifest
                    
if you are setting up this repo
dotnet tool install --local bdna --version 0.5.6
                    
This package contains a .NET tool you can call from the shell/command line.
#tool dotnet:?package=bdna&version=0.5.6
                    
nuke :add-package bdna --version 0.5.6
                    

BenchmarkDotNet Analyser

Nuget

Build Test and Package

Contributor Covenant

A .NET tool for analysing BenchmarkDotNet results.

BDNA aggregates and analyses BenchmarkDotNet results for performance degredations. If you want to ensure your critical code has acceptable performance in your CI pipelines BDNA might help you.


Getting started

Installation

To install BDNA, you'll need the .NET 8 SDK or runtime. BDNA can be downloaded and installed from Nuget.


Building locally

By default, the build script will restore, build, run tests and package:

.\build.ps1

If you need to build up to a certain target just give the target's name:

.\build.ps1 "Unit Tests"

Usage

What BDNA needs from BenchmarkDotNet

BDNA analyses the full JSON report files from BenchmarkDotNet. These files have the suffix -report-full.json and are generated by benchmarks with the JsonExporterAttribute.Full attribute; they are usually found under ./BenchmarkDotNet.Artifacts/results folders. See Exporters for more information.

BDNA also requires benchmarks with full statistics, generated by the [MinColumn, MaxColumn, Q1Column, Q3Column, AllStatisticsColumn] benchmark attributes: see Statistics in the documentation.


Example

[MinColumn, MaxColumn, Q1Column, Q3Column, AllStatisticsColumn]
[JsonExporterAttribute.Full]    
public class Md5VsSha256Benchmark
{
    private readonly SHA256 _sha256 = SHA256.Create();
    private readonly MD5 _md5 = MD5.Create();
    private byte[] _data;

    [Params(1000, 10000, 100000)]
    public int N;

    [GlobalSetup]
    public void Setup()
    {
        _data = new byte[N];
        new Random(42).NextBytes(_data);
    }

    [Benchmark]
    public byte[] Sha256() => _sha256.ComputeHash(_data);

    [Benchmark]
    public byte[] Md5() => _md5.ComputeHash(_data);
}

How BDNA collects data

BDNA collects BenchmarkDotNet full JSON report files, as described above. BDNA will aggregate these results into a single dataset for follow-up analysis.

To aggregate use bdna aggregate giving the folder containing new results (--new), the folder containing a previous aggregated dataset (--aggregates), and the folder for the new dataset (--output).


Example

Aggregate results from ./BenchmarkDotNet.Artifacts/results into the dataset at ./aggregates and fold into the same dataset. A maximum of 100 benchmark runs will be retained. The new results are tagged with build version $BUILD_NUMBER:

dotnet bdna aggregate --new "./BenchmarkDotNet.Artifacts/results" --aggregates "./aggregates" --output "./aggregates" --runs 100 --build $BUILD_NUMBER

Aggregate benchmark results into a single dataset.

Usage: bdna aggregate [options]

Options:
  -new|--new <NEW_BENCHMARKS_PATH>                 The path containing new benchmarks results.
  -aggs|--aggregates <AGGREGATED_BENCHMARKS_PATH>  The path containing the dataset to roll into.
  -out|--output <OUTPUT_AGGREGATES_PATH>           The path for the new dataset.
  -runs|--runs <BENCHMARK_RUNS>                    The number of benchmark runs to keep when aggregating.
  -build|--build <BUILD_NUMBER>                    The new build's number/version. Optional.
  -builduri|--builduri <BUILD_URI>                 The new build's URL. Optional.
  -branch|--branch <BRANCH_NAME>                   The new build's branch name. Optional.
  -commit|--commit <COMMIT_SHA>                    The new build's commit SHA. Optional.
  -t|--tag <TAGS>                                  A tag for the new build. Optional, multiple tags can be given.
  -v|--verbose                                     Emit verbose logging.
  -?|-h|--help                                     Show help information.

--new: the folder containing a new benchmark run to fold into the aggregate dataset. This is typically the ./**/BenchmarkDotNet.Artifacts/results folder.

--aggregates: the folder containing previously aggregated data.

--output: the folder for the new dataset. The aggregates from --aggregates and the new results from --new will be placed into the --output path. Both the --aggregates and --output arguments can be the same.

--runs: the maximum number of benchmark results that are aggregated in --output.

--build: the new build's version number.

--builduri: the new build's URL.

--branch: the new build's branch name.

--tag: arbitrary tags to assign to the new benchmark run. Multiple tags can be assigned to the run.


How BDNA analyses benchmarks

Use bdna analyse to scan the aggregate dataset for degradations.

Every benchmark run (that is, the benchmark type, method and parameters) is analysed in isolation. For example, if your benchmarks have runs Dijkstra(Depth=1) & Dijkstra(Depth=2) each of these will be analysed independently, and not Dijkstra() as a whole.

From all the aggregated runs, BDNA picks the minimum mean time value per run as the baseline value, or whatever statistic you elect to analyse. The benchmark run that was added last is taken as the comparand: if this latest value is within your tolerances the analysis will pass, if not the analysis fails.

Successful checks will give a return code of 0, failures will return 1.


Example

Analyse the aggregates at ./aggregates, with a 10% tolerance, maximum of 5 errors, for those benchmarks containing simple or complex in their names, with verbose output:

dotnet bdna analyse --aggregates "./aggregates" --tolerance 10 --maxerrors 5 --filter *simple* --filter *complex* --verbose

Analyse a benchmark dataset for performance degradation.

Usage: bdna analyse [options]

Options:
  -tol|--tolerance <TOLERANCE>          Tolerance of errors from baseline performance.
  -max|--maxerrors <MAX_ERRORS>         The maximum number of failures to tolerate.
  -stat|--statistic <STATISTIC>         The result statistic to analyse.
  -f|--filter <FILTERS>                 Filter by class or namespace. Optional, multiple filters can be given.
  -aggs|--aggregates <AGGREGATES_PATH>  The path of the aggregated dataset to analyse.
  -v|--verbose                          Emit verbose logging.
  -?|-h|--help                          Show help information.

--aggregates: the folder containing the aggregated dataset. This is the same as the --output parameter from bdna aggregate.

--tolerance: the percentage deviance from the minimum value.

--maxerrors: the maximum number of errors for the analysis to pass. If this is 0 then any error will cause the analysis to fail.

--statistic: the statistic value, for each run, to use. By default this is MeanTime with MinTime, MaxTime, MedianTime, Q1Time, Q3Time, Gen0Collections, Gen1Collections, Gen2Collections & BytesAllocatedPerOp.

--filter: Filter for specific namespaces, types or methods. Simple wildcards are supported, e.g. -f * -f *Benchmark -f Benchmark*. Multiple filters can be specified and will be applied conjunctively.

If there are no degradations in performance, bdna analyse will give a return code of 0, otherwise 1 will be returned. This is what your CI pipeline must watch to fail builds.


Reporting

You can report on the aggregated benchmark dataset. Each benchmark run is exported, together with any build number, build URL, branch & tags that were taken at the time of aggregation, giving a time series of benchmarks per build.


Example

Generate CSV and JSON reports for the aggregates at ./aggregates, sending output to ./reports:

dotnet bdna report --aggregates "./aggregates" --reporter csv --reporter json --output "./reports"

Build reports from a benchmark dataset.

Usage: bdna report [options]

Options:
  -aggs|--aggregates <AGGREGATES_PATH>  The path of the aggregated dataset to analyse.
  -r|--reporter <REPORTERS>             The reporting style. Optional, multiple reporters can be given.
  -out|--output <OUTPUT_PATH>           The path for reports.
  -f|--filter <FILTERS>                 Filter by class or namespace. Optional, multiple filters can be given.
  -v|--verbose                          Emit verbose logging.
  -?|-h|--help                          Show help information.

--aggregates: the folder containing the aggregated dataset. This is the same as the --output parameter from bdna aggregate.

--output: the destination folder for reports.

--reporter: the reporter style to use. Multiple may be provided from Csv (the default) and Json.

--filter: Filter for specific namespaces, types or methods. Simple wildcards are supported, e.g. -f * -f *Benchmark -f Benchmark*. Multiple filters can be specified and will be applied conjunctively.


Contributing

How to Contribute

Report a security vulnerability

Security notes

Support

How we support this project


Further reading

License

Copyright notice

Our Code of Conduct


License

Distributed under the Apache 2.0 license. See LICENSE for more information.

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

This package has no dependencies.

Version Downloads Last Updated
0.5.6 96 1/7/2026
0.5.5 477 12/8/2025
0.5.4 813 6/23/2025
0.4.101 518 3/19/2025
0.4.3 206 6/23/2025
0.4.2 187 6/23/2025
0.3.305 1,726 9/3/2024
0.3.303-preview 154 9/3/2024
0.3.302-preview 158 9/3/2024
0.3.301 207 9/2/2024
0.3.299-preview 149 9/2/2024
0.3.297-preview 147 9/2/2024
0.3.295-preview 150 9/2/2024
0.3.294-preview 152 9/2/2024
0.3.293-preview 146 9/2/2024
0.3.292-preview 141 9/2/2024
0.3.291-preview 148 9/2/2024
0.3.290-preview 154 9/2/2024
0.3.289-preview 155 9/2/2024
0.3.286 1,566 4/14/2024
0.3.284-preview 223 4/14/2024
0.3.283-preview 207 4/14/2024
0.3.282-preview 217 4/14/2024
0.3.281-preview 225 4/14/2024
0.3.280-preview 205 4/14/2024
0.3.279-preview 221 4/12/2024
0.3.278-preview 227 4/12/2024
0.3.275 486 1/2/2024
0.3.273-preview 227 1/2/2024
0.3.272-preview 222 1/2/2024
0.3.271 499 1/2/2024
0.3.270 2,252 9/26/2023
0.3.268-preview 348 9/26/2023
0.3.88 215 3/17/2025
0.3.79 223 3/17/2025
0.3.74 213 3/17/2025
0.3.68 214 3/17/2025
0.3.61 213 3/17/2025
0.3.56 210 3/17/2025
0.3.48 215 3/17/2025
0.3.46 211 3/17/2025
0.3.44 218 3/17/2025
0.3.43-preview 185 3/17/2025
0.3.41-preview 189 3/17/2025
0.3.38 221 3/17/2025
0.3.36-preview 189 3/17/2025
0.3.9 218 3/17/2025
0.3.7-preview 183 3/17/2025
0.3.6 226 3/12/2025
0.3.4-preview 212 3/11/2025
0.3.2-preview 204 3/10/2025
0.2.267-preview 306 9/26/2023
0.2.266-preview 284 9/21/2023
0.2.263 533 9/20/2023
0.2.261-preview 275 9/20/2023
0.2.260 242 9/20/2023
0.2.258-preview 316 9/20/2023
0.1.257 329 9/20/2023
0.1.255-preview 302 9/20/2023
0.1.253-preview 293 9/20/2023
0.1.252-preview 296 9/20/2023
0.1.251-preview 328 9/20/2023