Skip to content
CAI
Software that uses CAICheck a score

dotnet/BenchmarkDotNet

68.7

Adequate · 5 August 2026

50.4k

lines of production code

C#

primary language

3

measurements over time

CAI band scale
CAI trend line
CAI lens gauges

What this system is

This system is a comprehensive .NET benchmarking framework that provides a robust engine for measuring and analyzing code performance. It supports diverse execution modes, including in-process and out-of-process runs across multiple .NET versions and platforms, while offering deep diagnostic capabilities such as memory profiling, disassembly, and hardware counter analysis. The framework also includes a static analysis layer to validate benchmark configurations at compile time and generates detailed reports in various formats, including statistical summaries, plots, and structured data exports.

How it got here

2013–2016 — Architectural refactoring and modernization

47 changes.

This period was defined by a comprehensive architectural overhaul of the BenchmarkDotNet framework, introducing a fluent configuration API, attribute-based setup, and a modular toolchain system. The team modernized the codebase by migrating to .NET 10, updating project formats, and refactoring core components like the engine, exporters, and diagnosers. Extensive unit and integration tests were added to validate these changes and ensure stability across multiple .NET versions.

2017–2019 — Architecture modernization and extensibility

41 changes.

This period focused on a comprehensive architectural refactoring of the BenchmarkDotNet codebase, introducing a modular engine, a new characteristic system, and a flexible filtering framework. The team expanded runtime support to include .NET 10/11, WebAssembly, and NativeAOT, while also adding in-process execution and Roslyn-based toolchains. Significant effort was also dedicated to improving test coverage and establishing project templates for easier adoption.

2020–2025 — Platform and toolchain expansion

47 changes.

This period focused on significantly expanding BenchmarkDotNet's execution capabilities by introducing new toolchains for WebAssembly, NativeAOT, and in-process IL emission. The scope of supported platforms was broadened to include ARM64 disassembly, macOS CPU detection, and .NET 10/11 support, while the build system was refactored for better maintainability.

2026 — Serialization and test infrastructure modernization

7 changes.

The project replaced the external SimpleJson library with System.Text.Json, introducing new serialization classes and custom converters for handling special numeric values. Concurrently, the test suite was expanded with comprehensive coverage for serialization, environment detection, and benchmark execution, alongside the introduction of mock implementations and environment-specific test attributes.

Features

Add --list command-line option to display available benchmarks

Users can now use the --list flag to print the names of all available benchmarks. The output can be displayed as a flat list or as a hierarchical tree, controlled by the new ListBenchmarkCaseMode enum (Flat or Tree). This is implemented via new classes in the ConsoleArguments/ListBenchmarks directory, including a printer interface and specific formatters for each output style.

src/BenchmarkDotNet/ConsoleArguments/ListBenchmarks · high confidence

Add DotMemory memory profiling support

Users can now use the DotMemoryDiagnoser to profile memory usage during benchmarks. This new feature allows capturing memory snapshots and analyzing heap states for .NET Framework (4.6.1+), .NET Core 3.0+, and .NET 10/11 runtimes on Windows and Linux, while explicitly excluding Mono, NativeAOT, and Wasm targets.

src/BenchmarkDotNet.Diagnostics.dotMemory · high confidence

Add DotTrace profiler integration to BenchmarkDotNet

Users can now use the JetBrains dotTrace profiler for performance analysis by applying the \[DotTraceDiagnoser\] attribute or configuring the DotTraceDiagnoser. This new diagnostic tool supports a wide range of .NET runtime versions (from .NET 4.6.1 through .NET 11) and specific runtimes like R2R and HostProcess, enabling deep profiling of benchmarked applications.

src/BenchmarkDotNet.Diagnostics.dotTrace · high confidence

Add F\# sample project with tail-call diagnoser

A new F\# sample project has been added to demonstrate benchmarking capabilities, including a comparison of standard dictionary lookups and a new tail-call diagnoser that analyzes recursive function optimizations.

samples/BenchmarkDotNet.Samples.FSharp · high confidence

Add OpenMetrics exporter for benchmark results

A new OpenMetrics exporter has been introduced to the BenchmarkDotNet tooling, allowing users to export benchmark statistics—including execution time, error, standard deviation, percentiles, and GC stats—as OpenMetrics-formatted files. This adds a new output format option alongside existing exporters, enabling easier integration with OpenMetrics-compatible monitoring systems.

src/BenchmarkDotNet/Exporters/OpenMetrics · high confidence

Add ScottPlot-based bar and box plot exporters

A new \ScottPlotExporter\ implementation has been added to the \BenchmarkDotNet.Exporters.Plotting\ namespace. This exporter generates \.png\ files for bar plots and box plots of benchmark results, with configurable dimensions, font sizes, and label rotation. The exporter is enabled by default and produces separate plot files for each benchmark, supporting both bar and box plot visualizations as specified by the \IncludeBarPlot\ and \IncludeBoxPlot\ properties.

src/BenchmarkDotNet.Exporters.Plotting · high confidence

Add macOS CPU detection via sysctl

Users on macOS will now see accurate CPU information (processor name, core counts, and frequencies) in benchmark reports. This is enabled by new \MacOsCpuDetector\ and \SysctlCpuInfoParser\ classes that parse the output of the \sysctl\ command to populate \CpuInfo\.

src/BenchmarkDotNet/Detectors/Cpu/macOS · high confidence

Add native disassembly support for ARM64

Users can now disassemble benchmarks running on ARM64 Linux and macOS. This change introduces a new \Arm64Disassembler\ and supporting classes (\Arm64InstructionFormatter\, \Arm64Asm\) to handle ARM64-specific instruction decoding, register tracking, and precode/stub resolution. The \DisassemblyDiagnoser\ now selects the appropriate disassembler based on the target platform, enabling native code analysis for ARM64 workloads.

src/BenchmarkDotNet/Disassemblers · high confidence

Added launch profiles for BenchmarkDotNet samples

The samples project now includes a launchSettings.json file that defines several run profiles for executing benchmarks, including specific configurations for 'IntroBasic' benchmarks (both standard and in-process), as well as utility commands for listing, info, help, and version. This allows developers to easily launch and test different benchmark scenarios directly from their IDE or command line.

samples/BenchmarkDotNet.Samples/Properties · high confidence

Added scripts to install templates from source

New shell scripts (install-from-source.bat and install-from-source.sh) have been added to the templates directory. These scripts allow users to build, pack, and install the BenchmarkDotNet templates directly from the source code, ensuring the template ID matches the NuGet package rather than a folder path, which prevents conflicts with existing templates.

templates · high confidence

Attribute-based configuration for all supported exporters

Users can now apply attributes to mark benchmark classes or assemblies to configure export formats. New attributes include AsciiDoc, CSV (with configurable separators), HTML, JSON (with Brief/Full/Compressed variants), Markdown (with GitHub/StackOverflow/Atlassian dialects), OpenMetrics, Plain text, R Plot, and XML (with Brief/Full/Compressed variants). Each attribute implements the new ExporterConfigBaseAttribute, allowing declarative setup of export behavior directly on benchmark code.

src/BenchmarkDotNet/Attributes/Exporters · high confidence

Changelog generation is now fully automated via new build tools

The build system now includes new C\# classes (ChangelogBuilder and ChangelogDetailsBuilder) that automatically fetch and generate the project's changelog. This automation pulls issue and pull request data from GitHub milestones and compares commits between versions to produce structured Markdown files for documentation. This replaces the previous manual or less automated process, ensuring the changelog is consistently updated with resolved issues, merged pull requests, and contributor acknowledgments for each release.

build/BenchmarkDotNet.Build/Runners/Changelog · high confidence

Expanded sample library with new benchmarking patterns and diagnostics

The samples project has been significantly expanded with numerous new example files demonstrating various BenchmarkDotNet features. This includes new samples for argument handling (IntroArguments, IntroArgumentsPriority, IntroArgumentsSource), baseline comparisons (IntroBenchmarkBaseline, IntroCategoryBaseline), cancellation support (IntroCancellationToken), category-based filtering (IntroCategories, IntroCategoryDiscoverer), cold start analysis (IntroColdStart), and complex parameter handling (IntroComparableComplexParam). The update also adds samples for various diagnosers including disassembly (IntroDisassembly, IntroDisassemblyAllJits, IntroDisassemblyDry, IntroDisassemblyRyuJit), memory profiling (IntroDotMemoryDiagnoser), code profiling (IntroDotTraceDiagnoser), event pipe profiling (IntroEventPipeProfiler, IntroEventPipeProfilerAdvanced), exception tracking (IntroExceptionDiagnoser), JIT statistics (IntroJitStatsDiagnoser), and in-process execution (IntroInProcess, IntroInProcessWrongEnv). Additional samples cover configuration sources (IntroConfigSource, IntroConfigUnion), environment variables (IntroEnvVars), custom Mono runtime configurations (IntroCustomMono, IntroCustomMonoArguments), deferred execution pitfalls (IntroDeferredExecution), export formats (IntroExport, IntroExportJson, IntroExportXml), filtering (IntroFilters), GC modes (IntroGcMode), hardware counters (IntroHardwareCounters), and more.

samples/BenchmarkDotNet.Samples · high confidence

Introduce CoreRun toolchain for .NET Core benchmarking

Added new files (CoreRunGenerator.cs, CoreRunPublisher.cs, CoreRunToolchain.cs) that enable running benchmarks using the CoreRun executable. This toolchain allows users to execute .NET Core applications with a specific CoreRun binary, including logic to copy and update dependencies within the CoreRun directory.

src/BenchmarkDotNet/Toolchains/CoreRun · high confidence

Introduce ExecuteParameters to consolidate execution context

A new ExecuteParameters class has been added to the Toolchains/Parameters directory. This class aggregates the context required to execute a benchmark, including build results, benchmark case and ID, logger, resolver, launch index, and diagnoser information. This change groups execution-related data into a single parameter object, simplifying how execution context is passed through the toolchain.

src/BenchmarkDotNet/Toolchains/Parameters · medium confidence

Introduce InProcessEmit toolchain for in-process benchmarking via IL emission

Added a new \InProcessEmitToolchain\ and its supporting components (\InProcessEmitGenerator\, \InProcessEmitBuilder\, \InProcessEmitExecutor\, etc.) that enable running benchmarks in-process by emitting IL code. This new toolchain allows benchmarks to be executed directly within the current process, potentially offering lower overhead compared to traditional out-of-process execution. The implementation includes a dedicated \InProcessEmitSettings\ class and handles execution on a separate thread by default, with support for apartment state and execution context management.

src/BenchmarkDotNet/Toolchains/InProcess/Emit · high confidence

Introduce InProcessNoEmit toolchain for in-process benchmarking

A new 'InProcessNoEmit' toolchain has been added to BenchmarkDotNet, allowing benchmarks to be executed in-process via reflection rather than emitting dynamic code. This new implementation, located in the \src/BenchmarkDotNet/Toolchains/InProcess/NoEmit\ directory, introduces a suite of action classes (e.g., \BenchmarkActionVoid\, \BenchmarkActionTask\) that handle workload execution, setup, and cleanup. The toolchain supports various return types including \void\, \Task\, \ValueTask\, and \async\ enumerables, and can be configured to run on a separate thread with a fresh execution context. This provides an alternative execution path for users who prefer or require in-process benchmarking without dynamic code generation.

src/BenchmarkDotNet/Toolchains/InProcess/NoEmit · high confidence

Introduce InProcessToolchain with environment validation and thread execution options

Added new files for the in-process execution engine, including InProcessHost, InProcessSettings, and InProcessValidator. The InProcessSettings class introduces an ExecuteOnSeparateThread option to control whether benchmarks run on the same or separate threads. The InProcessValidator enforces that the job configuration matches the actual environment (e.g., JIT, platform, runtime) and ensures the correct toolchain is used, failing if arguments are passed to unsupported toolchains.

src/BenchmarkDotNet/Toolchains/InProcess · high confidence

Introduce MSBuild task for assembly weaving

A new MSBuild task, WeaveAssemblyTask, has been added to the weaver project. This task processes target assemblies by applying aggressive optimization to methods and adjusting method implementation attributes for benchmark methods, utilizing the AsmResolver.DotNet library for assembly manipulation.

src/BenchmarkDotNet.Weaver/src · medium confidence

Introduce Mono AOT LLVM toolchain for benchmarking

Added a new Mono AOT LLVM toolchain that enables running benchmarks using the LLVM-based AOT compiler. The change introduces a new \MonoAotCompilerMode\ enum (supporting mini, llvm, and wasm modes) and the corresponding generator and toolchain classes to build and execute AOT-compiled benchmarks.

src/BenchmarkDotNet/Toolchains/MonoAotLLVM · high confidence

Introduce MonoAOT toolchain for Ahead-of-Time compilation

Added a new MonoAOT toolchain that enables Ahead-of-Time compilation for Mono runtimes. This new toolchain includes dedicated components for generation (MonoGenerator), building (MonoAotBuilder), and execution, along with validation rules to ensure the correct Mono runtime is configured. The MonoAOT toolchain requires the Runtime property to be explicitly set to an instance of MonoRuntime class and validates that the MonoBclPath exists if provided.

src/BenchmarkDotNet/Toolchains/Mono · high confidence

Introduce Reflection.Emit helper classes for dynamic code generation

Added a new set of internal helper classes in the \src/BenchmarkDotNet/Helpers/Reflection.Emit\ directory to support dynamic IL generation. These include \EmitParameterInfo\ for creating parameter metadata, and extension classes (\IlGeneratorCallExtensions\, \IlGeneratorDefaultValueExtensions\, \IlGeneratorEmitOpExtensions\, \IlGeneratorStatementExtensions\, \MethodBuilderExtensions\, and \TypeBuilderExtensions\) that provide optimized IL emission for method calls, default value initialization, and loop structures. These utilities streamline the process of generating benchmark code at runtime.

src/BenchmarkDotNet/Helpers/Reflection.Emit · high confidence

Introduce Roslyn-based toolchain for building benchmarks

The Roslyn toolchain is now available for building benchmarks, providing an alternative to the previous MSBuild-based approach. This new toolchain uses the Roslyn compiler directly, which changes how benchmarks are compiled and executed. The toolchain is restricted to .NET Framework and legacy Mono environments, as indicated by the validation logic that rejects other runtime types. It also enforces deterministic builds and handles missing references by dynamically loading assemblies. Users should be aware that this toolchain does not support all features available in the MSBuild toolchain, such as custom build configurations or the RetainVM option.

src/BenchmarkDotNet/Toolchains/Roslyn · high confidence

Introduce WebAssembly (WASM) toolchain for running benchmarks in JavaScript environments

Adds a new WasmToolchain that enables running .NET benchmarks in WebAssembly runtimes (e.g., Node.js, browsers) via a new WasmExecutor and WasmGenerator. The toolchain supports both AOT and interpreter modes, generates necessary project files and JavaScript entry points, and uses either WebSocket or file-based IPC for communication with the benchmark process.

src/BenchmarkDotNet/Toolchains/MonoWasm · high confidence

Introduce vstestadapter filter support with improved exception logging

Added a new LoggerHelper utility class to centralize logging of informational, error, and warning messages with timestamps and source context. Implemented a TestCaseFilter class that supports filtering test cases by display name, fully qualified name, and custom traits, while adding robust null checks and improved exception logging for test platform format and invocation errors.

src/BenchmarkDotNet.TestAdapter/Utility · high confidence

Introduces a new configuration model with a fluent API and immutable config

The configuration system has been refactored to support a fluent API for building and configuring benchmarks. A new \IConfig\ interface and \ManualConfig\ class allow users to configure benchmarks using a chain of extension methods (e.g., \AddLogger\, \AddDiagnoser\, \WithOrderer\). The configuration is finalized into an \ImmutableConfig\ to ensure thread-safety and prevent accidental modification. This change also introduces \ConfigOptions\ as a flags enum to control various behaviors like \KeepBenchmarkFiles\ and \StopOnFirstError\, and adds new configuration types such as \DebugConfig\ for easier debugging and \DefaultConfig\ as the default instance.

src/BenchmarkDotNet/Configs · high confidence

Major refactoring of the export system with new exporters and interfaces

The export system has been significantly restructured. A new \IExporter\ interface and \ExporterBase\ abstract class provide a unified contract for all exporters. A \CompositeExporter\ is introduced to manage multiple exporters, which now handle their own file writing via \ExportAsync\ methods that accept a \CancelableStreamWriter\. New exporters include \AsciiDocExporter\, \BenchmarkReportExporter\, \HtmlExporter\, \InstructionPointerExporter\, \PlainExporter\, and \PerfonarJsonExporter\/\PerfonarMdExporter\. The \FullNameProvider\ is made public for reuse. The \DefaultExporters\ static class aggregates all default instances. The \RPlotExporter\ is updated to use the new interface and dependencies.

src/BenchmarkDotNet/Exporters · high confidence

Migrate solution format from .sln to .slnx and add .editorconfig

The project has migrated from the legacy .sln format to the new .slnx XML-based solution format, which allows for better organization of projects and files within the solution. Additionally, a new .editorconfig file has been added to enforce consistent code formatting, indentation, and style rules across the codebase, ensuring that all developers and tools adhere to the same coding standards.

(repo-wide) · high confidence

NativeAOT toolchain now supports .NET 10 and .NET 11

The NativeAOT toolchain has been updated to include pre-configured support for .NET 10 and .NET 11, allowing users to run benchmarks against these newer .NET versions. The update also introduces new builder options to configure the IL compiler's optimization preferences (Speed or Size) and instruction sets, enabling users to tailor the native compilation process for specific performance or size requirements.

src/BenchmarkDotNet/Toolchains/NativeAot · high confidence

New C\#, F\#, and VB.NET project templates for BenchmarkDotNet

The repository has added new project templates for C\#, F\#, and VB.NET, each providing a ready-to-use benchmarking project structure. These templates include configuration classes, entry points, and sample benchmark methods, with support for multiple .NET and .NET Framework versions. Users can now generate new benchmark projects using the 'dotnet new' command with the 'benchmark' short name, streamlining the setup process for performance testing.

templates/templates · high confidence

New CSV and CSV-measurements exporters for benchmark results

The CSV exporter now supports configurable separators (comma, semicolon, or current culture) and applies the summary style by default, ensuring consistent formatting. A new CSV-measurements exporter is introduced to export individual measurement data, including target, job, parameters, and iteration details, with proper escaping and header generation.

src/BenchmarkDotNet/Exporters/Csv · high confidence

New ETW tracing infrastructure for Windows diagnostics

Added new classes in the Tracing namespace to parse Windows Event Tracing (ETW) logs for benchmark diagnostics. This includes the BenchmarkEvent and IterationEvent trace event models, along with parsers (EngineEventLogParser, NativeMemoryLogParser, TraceLogParser) that extract metrics such as total operations, instruction pointers, and native memory allocations from ETW sessions. This enables the Windows diagnostics module to analyze engine-level events and hardware performance counters for benchmark iterations.

src/BenchmarkDotNet.Diagnostics.Windows/Tracing · high confidence

New Roslyn analyzers enforce correct usage of BenchmarkDotNet attributes

The BenchmarkDotNet.Analyzers project now includes a suite of Roslyn-based static analysis rules that validate the correct usage of BenchmarkDotNet attributes at compile time. These new diagnostics, such as BDN1503 (ensuring \[Arguments\] methods have parameters) and BDN1600-BDN1605 (validating \[BenchmarkCancellation\] usage), help users catch configuration errors early. The release also removes the BDN1100 rule, as generic type arguments now support abstract classes, and adds support for detecting incorrect usage of \[Arguments\] and \[Params\] attributes.

src/BenchmarkDotNet.Analyzers · high confidence

New VSTest adapter for running benchmarks as tests

A new VSTest adapter has been added to BenchmarkDotNet, allowing users to discover and run their benchmarks directly through the Visual Studio Test Explorer and the dotnet test command. The adapter maps each benchmark to a VSTest TestCase, enabling standard test discovery, filtering, and execution workflows. This change introduces a new execution path where benchmarks are treated as test cases, with results and logs forwarded to the VSTest host.

src/BenchmarkDotNet.TestAdapter · high confidence

New Windows-specific diagnosers and profilers for deeper performance analysis

Added several new diagnostic tools for Windows users: a Concurrency Visualizer profiler that generates .CvTrace files for Visual Studio's Concurrency Visualizer; an EtwProfiler for collecting ETW traces and hardware counter metrics; an InliningDiagnoser to track JIT inlining success/failure; a TailCallDiagnoser to monitor tail calls; a JitStatsDiagnoser to report JIT compilation statistics; and a NativeMemoryProfiler to track native memory allocations. These tools provide more granular insights into JIT behavior, memory usage, and concurrency patterns during benchmark execution.

src/BenchmarkDotNet.Diagnostics.Windows · high confidence

New attributes for configuring benchmark behavior and diagnostics

A suite of new attributes has been added to simplify configuring BenchmarkDotNet via code annotations. These include \ArtifactsPathAttribute\ to set the output directory, \ConfigAttribute\ to apply a custom \IConfig\, and \CategoryDiscovererAttribute\ to control category discovery. Diagnostic and profiling capabilities are now accessible via attributes: \DisassemblyDiagnoserAttribute\ for code analysis, \EventPipeProfilerAttribute\ and \PerfCollectProfilerAttribute\ for performance profiling, \ExceptionDiagnoserAttribute\ for exception tracking, \MemoryDiagnoserAttribute\ for GC metrics, \ThreadingDiagnoserAttribute\ for lock contention, and \HardwareCountersAttribute\ for hardware counters. Additional configuration attributes include \GroupBenchmarksByAttribute\ for logical grouping, \HideColumnsAttribute\ to suppress specific columns, \KeepBenchmarkFilesAttribute\ to retain intermediate files, \OrdererAttribute\ to control benchmark ordering, \StopOnFirstErrorAttribute\ to halt on failure, \UnicodeConsoleLoggerAttribute\ for console output, and \WakeLockAttribute\ to prevent system sleep during execution.

src/BenchmarkDotNet/Attributes · high confidence

New attributes to configure validation behavior for benchmarks

Added three new attributes in the BenchmarkDotNet.Attributes namespace: ExecutionValidatorAttribute, ReturnValueValidatorAttribute, and the abstract base class ValidatorConfigBaseAttribute. These attributes allow users to configure validation rules for benchmark execution and return values, with the ability to control whether validation failures should cause the benchmark to fail or continue.

src/BenchmarkDotNet/Attributes/Validators · high confidence

New baseline comparison columns for memory and statistics

The summary table now includes new columns to compare benchmarks against a baseline. A 'Baseline' column indicates which benchmark is the baseline. New 'Ratio' and 'RatioSD' columns show the mean and standard deviation of the ratio distribution between current and baseline results, supporting Value, Percentage, and Trend display styles. Additionally, an 'Alloc Ratio' column is introduced to compare allocated memory between the current and baseline benchmarks. These columns are conditionally shown based on the presence of a baseline and, for memory, the presence of a memory diagnoser.

src/BenchmarkDotNet/Columns · high confidence

New benchmarking attributes and base classes for parameterized and lifecycle control

The \BenchmarkDotNet.Annotations\ library now includes a comprehensive set of new attributes to define benchmark behavior and lifecycle hooks. This includes \ArgumentsAttribute\ and \ParamsAttribute\ for supplying test data, \ParamsSourceAttribute\ and \ArgumentsSourceAttribute\ for referencing external data sources, and \ParamsAllValuesAttribute\ for exhaustive parameter testing. Lifecycle management is supported via \GlobalSetup\, \GlobalCleanup\, \IterationSetup\, and \IterationCleanup\ attributes. Additionally, \BenchmarkAttribute\ now exposes source code location metadata, \BenchmarkCategoryAttribute\ supports class-level categorization, and \PriorityAttribute\ allows controlling the display order of parameters. New base classes \TargetedAttribute\ and \PriorityAttribute\ provide the foundation for these features.

src/BenchmarkDotNet.Annotations/Attributes · high confidence

New column attributes for benchmark statistics and statistical testing

A new set of column attributes has been added to the BenchmarkDotNet.Attributes namespace, allowing users to easily include specific statistical columns in their benchmark results. This includes standard statistics (Mean, Median, Min, Max, StdDev, StdError, Kurtosis, Skewness, Q1, Q3), as well as new attributes for Confidence Interval Error, Operations Per Second, and a Statistical Test column that supports configurable thresholds and significance levels for Welch's t-test.

src/BenchmarkDotNet/Attributes/Columns · high confidence

New command-line argument parsing and configuration system

The console argument parsing has been refactored to use a new \CommandLineOptions\ model and \ConfigParser\ pipeline, introducing support for response files (via the \@filename\ syntax) and providing better error handling and suggestions for typos in benchmark names. Users can now pass configuration options via command-line arguments, including new flags for threading and exception diagnosers, hardware counters, and build timeout settings.

src/BenchmarkDotNet/ConsoleArguments · high confidence

New diagnostic attributes for Windows profiling tools

Added new attribute-based configuration options for several Windows-specific profilers and diagnosers, allowing users to enable them via simple class attributes. The update introduces ConcurrencyVisualizerProfilerAttribute, EtwProfilerAttribute, InliningDiagnoserAttribute, JitStatsDiagnoserAttribute, NativeMemoryProfilerAttribute, and TailCallDiagnoserAttribute. These attributes simplify setup by automatically attaching the corresponding profilers or diagnosers to the benchmark configuration.

src/BenchmarkDotNet.Diagnostics.Windows/Configs · high confidence

New disassembly report exporters

The Disassemblers/Exporters directory now includes new exporters for generating disassembly reports in HTML, Markdown, and combined formats. Specifically, CombinedDisassemblyExporter produces an HTML report comparing disassembly across different JITs or methods, while GithubMarkdownDisassemblyExporter and GithubMarkdownDiffDisassemblyExporter provide Markdown outputs, with the latter generating diffs between different JIT implementations. These new files introduce the DisassemblyPrettifier for formatting assembly code and a SymbolResolver for address-to-symbol mapping, enabling users to export and compare disassembly results in more readable and shareable formats.

src/BenchmarkDotNet/Disassemblers/Exporters · high confidence

New extension methods for assembly, reflection, and runtime moniker mapping

The BenchmarkDotNet.Extensions namespace now includes a suite of new extension classes to support .NET 9, 10, and 11, NativeAOT, and Mono runtimes. AssemblyExtensions provides methods to detect JIT optimization and debug states. ReflectionExtensions adds utilities for resolving attributes, generating C\# type names, and finding runnable benchmarks. RuntimeMonikerExtensions maps runtime monikers to specific runtime versions and instances. Other new extensions include CommonExtensions for collection and string utilities, ConfigurationExtensions for platform and JIT settings, CultureInfoExtensions for list separators, DoubleExtensions for invariant string formatting, EncodingExtensions for template strings, Hashing for MurmurHash3, MathExtensions for rounding, MethodInfoExtensions for delegate creation, PathFeatures for long path support, and ReportExtensions for summary and statistics handling.

src/BenchmarkDotNet/Extensions · high confidence

New filter attributes for OS, architecture, and categories

Added new attributes to filter benchmarks by operating system, architecture, and categories. Users can now apply \[OperatingSystemsFilterAttribute\] to run benchmarks only on specific platforms (Windows, Linux, macOS, or Browser) or exclude them. \[OperatingSystemsArchitectureFilterAttribute\] allows filtering by CPU architecture. \[AllCategoriesFilterAttribute\] and \[AnyCategoriesFilterAttribute\] enable filtering by category tags. These attributes implement the existing filter infrastructure, allowing developers to control which benchmarks execute based on the host environment.

src/BenchmarkDotNet/Attributes/Filters · high confidence

New in-process and composite diagnoser infrastructure

The diagnoser subsystem has been refactored to support in-process diagnosables, allowing diagnosers to run within the benchmarked process itself. This introduces new interfaces (IInProcessDiagnoser, IInProcessDiagnoserHandler) and a CompositeInProcessDiagnoser to manage multiple in-process handlers. Existing diagnosers like ExceptionDiagnoser and EventPipeProfiler have been updated to use this new architecture, enabling features such as tracking exception frequencies and collecting trace files. The change also adds metric descriptors for allocated memory and native memory, and introduces a loader (DiagnosersLoader) to lazily load diagnosers, including Windows-specific ones from a separate assembly.

src/BenchmarkDotNet/Diagnosers · high confidence

New job configuration attributes for benchmarking

The BenchmarkDotNet.Attributes.Jobs namespace now includes new attributes to configure benchmark jobs: DryJobAttribute, InProcessAttribute, LegacyJitX64JobAttribute, LegacyJitX86JobAttribute, LongRunJobAttribute, MediumRunJobAttribute, MonoJobAttribute, RyuJitX64JobAttribute, RyuJitX86JobAttribute, ShortRunJobAttribute, SimpleJobAttribute, and VeryLongRunJobAttribute. These attributes allow users to declaratively specify job settings such as run strategy, iteration counts, and runtime environments directly on test classes or assemblies.

src/BenchmarkDotNet/Attributes/Jobs · high confidence

New job mutator attributes for fine-grained benchmark configuration

A new set of job mutator attributes has been introduced to allow configuring benchmark execution parameters directly via class or method attributes. This includes control over garbage collection behavior (GcConcurrent, GcForce, GcServer), iteration and invocation counts (InnerIterationCount, InvocationCount, IterationCount, Min/Max/MinIterationCount), warmup and min/max warmup counts, timing targets (IterationTime, MinIterationTime), error thresholds (MaxAbsoluteError, MaxRelativeError), JIT tiering, process launch count, outlier removal, memory randomization, and synchronous task consumption. These attributes provide a declarative way to customize the benchmarking process without relying solely on the fluent API or global configuration.

src/BenchmarkDotNet/Attributes/Mutators · high confidence

New parameter types for generated benchmark code

Added new code-generation classes for handling array and enum parameters in the auto-generated benchmark source code. The \ArrayParam\ class now supports multi-dimensional and jagged arrays, displaying their dimensions in the summary and generating correct C\# array initializers. The \EnumParam\ class preserves the underlying type information for enum values, ensuring correct source code generation for F\# interop and other scenarios. These changes improve the accuracy and compatibility of generated benchmark code.

src/BenchmarkDotNet/Code · high confidence

New result types for build, generation, and execution phases

The toolchain layer now exposes three new result types—BuildResult, GenerateResult, and ExecuteResult—to represent the outcomes of the build, code generation, and benchmark execution phases respectively. Users can now inspect detailed status (success/failure), error messages, and execution metrics (measurements, GC stats, exit codes) from each stage, enabling more precise diagnostics and handling of build or execution failures.

src/BenchmarkDotNet/Toolchains/Results · high confidence

New toolchain infrastructure: IGenerator, IBuilder, IExecutor, and ArtifactsPaths

The toolchain execution model has been refactored to use a new set of interfaces and classes that separate concerns. A new \ArtifactsPaths\ class now encapsulates all file and directory paths used during the build and execution phases. The \IGenerator\ interface (implemented by \GeneratorBase\) handles project and code generation, while \IBuilder\ and \IExecutor\ (implemented by \DotNetCliPublisher\ and \Executor\ respectively) manage the build and process execution steps. This structure allows for more modular toolchain implementations, such as the new \R2RToolchain\ which leverages these abstractions to support Ready-to-Run (R2R) compilation for .NET 8, 9, 10, and 11.

src/BenchmarkDotNet/Toolchains · high confidence

Restructured Job configuration into dedicated mode classes

The Job configuration model has been refactored to use dedicated mode classes (AccuracyMode, EnvironmentMode, InfrastructureMode, RunMode, and MetaMode) that encapsulate specific benchmarking settings. This change introduces new extension methods on the Job class to configure these settings, such as WithGcServer, WithIterationCount, and WithJit, providing a more modular and fluent API for setting up benchmark jobs.

src/BenchmarkDotNet/Jobs · high confidence

Runtimes refactored into dedicated classes with expanded version support

The runtime detection and configuration logic has been restructured into specific classes (ClrRuntime, CoreRuntime, MonoRuntime, NativeAotRuntime, R2RRuntime, WasmRuntime, and MonoAotLLVMRuntime) to improve maintainability and extensibility. This change adds support for .NET 10 and .NET 11 across the respective runtime types, updates .NET Framework support to include 4.6.1, 4.6.2, 4.7.1, 4.7.2, 4.8, and 4.8.1, and introduces new runtime monikers and detection capabilities for WebAssembly (Wasm) and NativeAOT environments.

src/BenchmarkDotNet/Environments/Runtimes · high confidence

Support for async and async-enumerable benchmarks in the in-process emit toolchain

The in-process emit toolchain now generates code for benchmarks that return async types (such as Task, ValueTask, or custom awaitables) and async enumerables. This is achieved through new emitters (AsyncCoreEmitter, AsyncEnumerableCoreEmitter) that emit IL for async state machines, allowing the in-process runner to correctly await and measure asynchronous workload methods. This extends the previous synchronous-only in-process execution to cover modern async benchmark patterns.

src/BenchmarkDotNet/Toolchains/InProcess/Emit/Implementation/Emitters · high confidence

Architecture

Centralized build configuration and tooling scripts

The build system has been refactored to centralize common properties, targets, and versioning logic. A new \build/common.props\ file now defines shared MSBuild properties such as assembly signing, nullable context, implicit usings, and the current version prefix (0.16.0). This is accompanied by \build/common.targets\ for packaging assets and \build/CodingStyle.ruleset\ to configure code analysis rules. Additionally, the repository now includes dedicated build scripts (\build/build.sh\, \build/build.ps1\, \build/build.bat\) that handle .NET SDK installation and execution, alongside a \build/versions.txt\ file that tracks the complete version history.

build · high confidence

Refactored build system into dedicated runner classes

The build and release automation logic has been restructured into specific runner classes (BuildRunner, DocumentationRunner, GitRunner, ReleaseRunner, and UnitTestRunner) within the build/BenchmarkDotNet.Build/Runners directory. This change organizes the Cake build script's responsibilities, separating concerns for building, documentation generation, Git operations, release publishing, and test execution, which should make the build process easier to maintain and extend.

build/BenchmarkDotNet.Build/Runners · high confidence

Behavioural changes

Add AssemblyInfo.cs with CLS compliance and InternalsVisibleTo

A new AssemblyInfo.cs file was added to the project, explicitly marking the assembly as CLS-compliant and exposing internal members to BenchmarkDotNet.IntegrationTests via InternalsVisibleTo.

src/BenchmarkDotNet.Diagnostics.Windows/Properties · high confidence

Add assembly metadata and visibility configuration for dotTrace diagnostics

The BenchmarkDotNet.Diagnostics.dotTrace module now includes an AssemblyInfo.cs file that declares the assembly as CLS-compliant and exposes its internal members to the BenchmarkDotNet.Tests assembly, enabling proper testing and compliance verification for the dotTrace diagnostics feature.

src/BenchmarkDotNet.Diagnostics.dotTrace/Properties · high confidence

Added AssemblyInfo configuration for dotMemory diagnostics

A new AssemblyInfo.cs file was added to the BenchmarkDotNet.Diagnostics.dotMemory project. This file configures the assembly as CLS-compliant and grants internal visibility to the BenchmarkDotNet.Tests assembly, enabling the test suite to access internal members for that specific diagnostic component.

src/BenchmarkDotNet.Diagnostics.dotMemory/Properties · high confidence

Added autogenerated entry points for BenchmarkDotNet test adapter

The BenchmarkDotNet.TestAdapter now includes autogenerated entry point files (EntryPoint.cs, .fs, .vb) that serve as the execution entry for running benchmarks. These files are marked as auto-generated to exclude them from StyleCop analysis and are added to projects to facilitate benchmark execution.

src/BenchmarkDotNet.TestAdapter/entrypoints · medium confidence

Build optimization: automatic filtering of unnecessary runtime and satellite assemblies

The BenchmarkDotNet build process now automatically reduces output size by removing unnecessary files from the bin directory. A new MSBuild targets file (BenchmarkDotNet.targets) detects the target platform and runtime identifier, then filters out non-matching runtime assets from the Capstone library and removes satellite assemblies from Microsoft.CodeAnalysis and Microsoft.TestPlatform. Additionally, a new .DotSettings file configures the IDE to skip specific namespace folders, supporting a flatter namespace structure for attributes, exporters, filters, jobs, mutators, validators, and toolchains.

src/BenchmarkDotNet · medium confidence

Build system introduces Repo and VersionHistory metadata classes

The build infrastructure now includes new C\# classes to manage repository and versioning metadata. The Repo class centralizes GitHub repository configuration, including the owner, name, branch names (master, docs-stable, docs-changelog), and a method to fetch the number of dependent projects from the GitHub API. The VersionHistory class parses a version file to extract the first commit hash, the current version, and a list of stable versions, supporting automated changelog and documentation generation workflows.

build/BenchmarkDotNet.Build/Meta · high confidence

Build system restructured with new Cake.Frosting tasks and centralized context

The build process has been refactored to use a new \BenchmarkDotNet.Build\ project based on Cake.Frosting. This introduces a centralized \BuildContext\ that manages build configuration, file paths, and runners for unit tests, documentation, and releases. Command-line arguments are now parsed by a dedicated \CommandLineParser\ that supports task-specific help and options. New tasks include \pack-weaver\, \restore\, \build\, \unit-tests\, \analyzer-tests\, \in-tests-full\, \in-tests-core\, and \all-tests\, each with structured help information and example usage. The build script now supports MSBuild properties and verbosity settings via command-line arguments, and CI builds are automatically detected to adjust compilation settings.

build/BenchmarkDotNet.Build · high confidence

Centralized assembly metadata and versioning logic

The library now uses a centralized \BenchmarkDotNetInfo\ class to manage versioning and assembly metadata. This change removes the \AssemblyInformationalVersion\ from the public \BrandVersion\ (stripping build metadata after the '+') and applies \CLSCompliant(true)\ to the assembly. Additionally, \InternalsVisibleTo\ attributes are explicitly defined for test projects and diagnostic tools, ensuring consistent access to internal members across the solution.

src/BenchmarkDotNet/Properties · high confidence

Centralizes and exposes internal naming conventions for the in-process runnable template

The in-process toolchain's code generation now relies on a new \RunnableConstants\ class that defines all string literals used for method, field, and type naming (e.g., \op\Implicit\, \\\TrickTheJIT\\\, \\\_GlobalSetup\). This change extracts these hardcoded strings from the \RunnableReflectionHelpers\ and other parts of the \InProcess\ toolchain into a single source of truth, ensuring consistent naming across the generated runnable classes.

src/BenchmarkDotNet/Toolchains/InProcess/Emit/Implementation/Runnable · high confidence

Complete rewrite of the Reports namespace with new data models and table generation

The BenchmarkDotNet Reports namespace has been entirely rewritten to introduce new core data models and table generation logic. A new \BenchmarkReport\ class now encapsulates execution results, measurements, and environment info, while \Measurement\ and \Metric\ structs provide structured data for individual runs and custom metrics. The \Summary\ class has been refactored to manage reports, baselining strategies, and precision management via \DisplayPrecisionManager\. Additionally, \SummaryTable\ and \SummaryStyle\ have been updated to support new column hiding, logical grouping, and text justification features, enabling more flexible and accurate benchmark reporting.

src/BenchmarkDotNet/Reports · high confidence

Expanded runtime and toolchain support for .NET 10, .NET 11, and WebAssembly

The RuntimeMoniker enumeration has been updated to include support for .NET 10.0 and .NET 11.0, alongside corresponding NativeAOT and WebAssembly (Wasm) configurations for .NET 10 and .NET 11. This allows BenchmarkDotNet to target and benchmark applications built on these newer .NET versions and runtime configurations.

src/BenchmarkDotNet.Annotations/Jobs · high confidence

Generated benchmark code now uses full type names to prevent naming conflicts

The auto-generated C\# code templates (BenchmarkProgram.txt, BenchmarkType.txt) and project files (CsProj.txt, WasmCsProj.txt, etc.) have been updated to use fully qualified type names (e.g., \global::System.Threading.Tasks.ValueTask\ instead of \ValueTask\). This change prevents naming conflicts with user-defined types that might share the same short name. Additionally, the generated code now includes \\#pragma warning disable CS0436\ to suppress type conflict warnings, and the generated project files disable analyzers and debug symbols to avoid build issues and Roslyn bugs.

src/BenchmarkDotNet/Templates · high confidence

Improved CPU detection on Windows and Linux with fallbacks for missing tools

CPU information is now detected using multiple strategies to ensure accuracy and availability. On Windows, the system attempts to gather CPU details via the modern .NET ManagementObjectSearcher API, falling back to PowerShell WMI commands, and finally to the legacy WMIC tool if necessary. On Linux, a new detector parses /proc/cpuinfo and lscpu output. These changes ensure that benchmarking tools can reliably identify processor model, core counts, and clock speeds across different operating systems and environment configurations.

src/BenchmarkDotNet/Detectors/Cpu/Windows · high confidence

Improved file path generation and cleanup for benchmark artifacts

The helper classes for managing artifact file names and directory cleanup have been refactored to handle long paths and ensure consistent behavior across operating systems. The new \ArtifactFileNameHelper\ enforces Windows path length limits (260 characters) and a 1024-character common sense limit, generating shorter fallback names when full paths exceed these constraints. Additionally, the \FileCleanupHelper\ was introduced to robustly delete benchmark output directories and files, ignoring access-denied or in-use errors to prevent crashes during cleanup.

src/BenchmarkDotNet/Helpers · high confidence

Introduce new filter architecture for benchmark selection

The benchmark filtering system has been refactored to use a new \IFilter\ interface and a suite of specialized filter classes, including \AllCategoriesFilter\, \AnyCategoriesFilter\, \AttributesFilter\, \DisjunctionFilter\, \GlobFilter\, \NameFilter\, \SimpleFilter\, and \UnionFilter\. This change enables more flexible and composable ways to select which benchmarks to run, supporting category matching, attribute-based filtering, glob patterns, and logical combinations of multiple filters.

src/BenchmarkDotNet/Filters · high confidence

Introduces a new command-line option parsing infrastructure

The build system now uses a new \Options\ namespace containing \Option\, \BoolOption\, \StringOption\, and \KnownOptions\ classes to manage command-line arguments. This refactors how build tasks like \--verbosity\, \--exclusive\, and \--push\ are parsed and resolved, replacing the previous argument handling mechanism.

build/BenchmarkDotNet.Build/Options · high confidence

Migrate statistical calculations to Perfolizer and Pragmastat

The mathematical core of BenchmarkDotNet has been refactored to use the Perfolizer and Pragmastat libraries for statistical computations. This introduces new types such as \LegacyConfidenceInterval\, \MeasurementsStatistics\, \PercentileValues\, and \RatioStatistics\ to handle confidence intervals, outlier detection, and ratio calculations. Users will see improved accuracy in statistical tests, better handling of small sample sizes, and more robust outlier detection via the Tukey method. The \Statistics\ class now exposes \OriginalValues\ and \Percentiles\ for external tooling, and the \RankHelper\ uses the new \MannWhitneyTest\ for ranking benchmarks.

src/BenchmarkDotNet/Mathematics · high confidence

New CPU instruction set detection for .NET 10+ and ARM/AVX10 support

The CPU detector now includes a new \HardwareIntrinsics\ class that detects x86 and ARM64 hardware intrinsics, including AVX10 and AVX512v2/v3 support for .NET 10+. This enables more precise CPU feature reporting in benchmark results for modern instruction sets.

src/BenchmarkDotNet/Detectors/Cpu · high confidence

New JSON export format with configurable output levels

The JSON exporter has been refactored to support multiple output profiles: Brief, Full, and Compressed variants, allowing users to choose between detailed benchmark data and compact summaries. The exported JSON now includes specific fields such as FullName for xunit-performance migration compatibility, HardwareIntrinsics status, and MemoryDiagnoser statistics. This change makes the JSON export more extensible and provides users with clearer control over the volume of data exported.

src/BenchmarkDotNet/Exporters/Json · medium confidence

New logging infrastructure with thread-safe and async process output reading

The logging system has been refactored to improve reliability and concurrency. A new \ILogger\ interface and \CompositeLogger\ provide a thread-safe way to write to multiple loggers simultaneously. The \AsyncProcessOutputReader\ now uses a \ConcurrentQueue\ and channels to safely read process output asynchronously, preventing race conditions and hangs. Additionally, new logger implementations such as \AccumulationLogger\, \LinqPadLogger\, and \LogCapture\ offer specialized logging capabilities, while \ConsoleLogger\ and \LoggerWithPrefix\ provide enhanced output formatting.

src/BenchmarkDotNet/Loggers · high confidence

New ordering policies for benchmarks and summaries

The benchmark ordering system has been refactored to support configurable sorting policies. A new \JobOrderPolicy\ enum allows jobs to be sorted numerically (default) or by ordinal string comparison. The \DefaultOrderer\ now accepts \JobOrderPolicy\ and \MethodOrderPolicy\ parameters to control how benchmarks are ordered during execution. Additionally, \SummaryOrderPolicy\ and \MethodOrderPolicy\ enums are introduced to control how results are ordered in the final summary report, offering options like fastest/slowest, method, or declared order. This provides users with explicit control over the presentation and execution order of benchmarks.

src/BenchmarkDotNet/Order · high confidence

New portability and runtime detection infrastructure

The BenchmarkDotNet.Portability namespace has been refactored and expanded with new classes to improve runtime and environment detection. A new Antivirus class was added to represent antivirus software. A new JitInfo class was introduced to detect and report JIT compiler settings, including tiered compilation, OSR, and PGO states. RuntimeInformation was updated to better identify the current runtime, including support for new Mono, NativeAOT, and WASM environments. Additionally, new classes for detecting virtual machine hypervisors (HyperV, VMware, VirtualBox) and a CodeGenHelper for aggressive optimization flags were added.

src/BenchmarkDotNet/Portability · medium confidence

New validation rules for benchmark methods and configuration

BenchmarkDotNet now enforces stricter validation on benchmark methods and configuration. A new \AwaitableAsyncEnumerableAmbiguityValidator\ detects when a method returns an awaitable that also matches the async enumerable pattern, warning that it will be awaited rather than enumerated. The \BaselineValidator\ ensures that only one benchmark method or job in a logical group can be marked as a baseline. The \CompilationValidator\ now rejects static benchmark methods, non-public declaring types, sealed classes containing benchmarks, and methods using C\# keywords or illegal characters in their names. The \ConfigValidator\ warns if no loggers, exporters, or column providers are defined, and validates the \ArtifactsPath\ for invalid characters or permissions. Additionally, the \DeferredExecutionValidator\ flags benchmarks returning deferred execution types like \IEnumerable\ or \IQueryable\, and the \JitOptimizationsValidator\ warns about non-optimized assemblies. The \ParamsValidator\ and \ParamsAllValuesValidator\ enforce stricter rules on parameter attributes, such as preventing multiple parameter attributes on the same member and restricting \\[ParamsAllValues\]\ to bool, enum, and nullable types.

src/BenchmarkDotNet/Validators · medium confidence

Port Xamarin samples to .NET MAUI

The BenchmarkDotNet samples have been migrated from the legacy Xamarin.Forms framework to .NET MAUI. This update provides a modernized, cross-platform mobile application structure, including updated platform-specific entry points (Android, iOS, MacCatalyst, Windows), MAUI-specific UI components (AppShell, MainPage), and native configuration files required for each target platform.

samples/BenchmarkDotNet.Samples.Maui · high confidence

Redesigned XML exporter with new serialization architecture

The XML export functionality has been refactored to use a new internal serialization architecture. This introduces a dedicated \IXmlSerializer\ interface and a \SimpleXmlWriter\ abstraction, allowing for more flexible XML generation. The \XmlExporter\ class now supports \indentXml\ and \excludeMeasurements\ options to control output formatting and content. Additionally, the \SummaryDto\ and related Data Transfer Objects (DTOs) have been introduced to map benchmark data to the XML structure, ensuring that memory statistics like \BytesAllocatedPerOperation\ are correctly persisted in the final report.

src/BenchmarkDotNet/Exporters/Xml · high confidence

Refactor benchmark analyser infrastructure to use a new Conclusion-based reporting system

The analyser subsystem has been refactored to use a new \Conclusion\-based reporting system. This introduces a base \AnalyserBase\ class and a \CompositeAnalyser\ to manage multiple analyzers, each producing \Conclusion\ objects (Hints, Warnings, Errors) that are printed by a new \ConclusionHelper\. This change standardizes how analyzers report findings, affecting how users see warnings about environment issues, zero measurements, outliers, and other benchmarking anomalies.

src/BenchmarkDotNet/Analysers · high confidence

Refactored C\# project file generation for .NET Framework and .NET Core

The toolchain logic for generating .csproj files has been reorganized into dedicated classes: CsProjClassicNetToolchain for .NET Framework (4.6.1–4.8.1) and CsProjCoreToolchain for .NET Core/.NET 5+ (2.0–11.0). This change introduces explicit validation for unsupported configurations (e.g., RyuJit requirement, LINQPad incompatibility) and ensures that project settings like \PreserveCompilationContext\, \UserSecretsId\, and \EnablePreviewFeatures\ are correctly copied to the generated project file.

src/BenchmarkDotNet/Toolchains/CsProj · high confidence

Refactored DotNetCli toolchain into a new modular architecture

The DotNetCli toolchain implementation has been refactored into a new set of classes to improve modularity and maintainability. The build and execution logic is now handled by dedicated classes: \DotNetCliBuilder\ and \DotNetCliPublisher\ for building and publishing, \DotNetCliCommand\ and \DotNetCliCommandExecutor\ for managing the dotnet CLI process, and \DotNetCliGenerator\ for project generation. A new \CustomDotNetCliToolchainBuilder\ allows for more flexible configuration of custom toolchains. This change reorganizes the internal structure of the DotNetCli toolchain without altering its external behavior.

src/BenchmarkDotNet/Toolchains/DotNetCli · high confidence

Refactored OS and CPU detection with platform-specific implementations

The OS and CPU detection logic has been refactored to use dedicated detector classes. The \OsDetector\ now provides a singleton instance that resolves operating system information (macOS, Linux, Windows) using platform-specific checks, including WSL detection for Linux and registry-based UBR for Windows. The \CpuDetector\ has been introduced to handle cross-platform CPU detection by delegating to specific detectors for Windows, Linux, and macOS. This change replaces the previous monolithic or less structured detection approach with a more modular and maintainable architecture.

src/BenchmarkDotNet/Detectors · high confidence

Refactored benchmark engine architecture with new synchronization and execution models

The benchmark engine has been refactored to improve async handling, JIT tiering, and dead-code elimination. A new \BenchmarkSynchronizationContext\ ensures async continuations are posted back to the correct thread, while \DeadCodeEliminationHelper\ prevents JIT optimization from removing benchmark results. The \Engine\ class now uses a stage-based execution model (\EngineJitStage\, \EnginePilotStage\, \EngineActualStage\) to better manage JIT warmup, overhead measurement, and workload execution. Additionally, a \Consumer\ class and its extensions provide a robust way to consume benchmark results without affecting GC behavior.

src/BenchmarkDotNet/Engines · high confidence

Refactored benchmark execution model with new core classes

The benchmark execution logic has been restructured into new core classes: \BenchmarkCase\ (representing a single benchmark instance with its job and parameters), \BenchmarkRunInfo\ (grouping cases for a type), \BenchmarkConverter\ (converting types/methods to \BenchmarkRunInfo\), \BenchmarkPartitioner\ (grouping benchmarks by runtime/build settings), and \BuildPartition\ (managing build groups). These changes underpin the \BenchmarkRunner\ and \BenchmarkSwitcher\ to support features like apples-to-apples comparison, parallel builds, and improved validation, while maintaining the existing public API surface.

src/BenchmarkDotNet/Running · high confidence

Refactored benchmark identification and removed legacy benchmarking classes

The \BenchmarkId\ struct was added to the \BenchmarkDotNet.Running\ namespace to provide a robust, internal mechanism for identifying benchmarks within an executable, including logic to safely truncate long benchmark names for command-line arguments. Concurrently, several legacy classes (\Benchmark\, \BenchmarkCompetition\, \BenchmarkCompetitionTask\, \BenchmarkInfo\, \BenchmarkRun\, \BenchmarkRunList\) were removed from the \BenchmarkDotNet\ namespace, indicating a significant internal refactoring of the benchmarking execution model.

BenchmarkDotNet · high confidence

Refactored build helper utilities and GitHub API extensions

The build system now includes new helper classes, OctokitExtensions and Utils, which centralize logic for formatting GitHub user and commit data, parsing .NET verbosity levels, and determining target frameworks based on the CI job name (e.g., net10.0 for Linux/macOS/Windows core jobs, net472 for Windows full jobs). These changes streamline how the build process interacts with the GitHub API and manages environment-specific configurations.

build/BenchmarkDotNet.Build/Helpers · high confidence

Refactored parameter handling with new internal classes

The internal parameter handling logic has been refactored into a new set of classes: \ParameterDefinition\, \ParameterDefinitions\, \ParameterInstance\, \ParameterInstances\, \ParameterComparer\, \DeepEqualityComparer\, \ParameterEqualityComparer\, and \SmartParamBuilder\. This change introduces a more structured approach to managing benchmark parameters, including improved comparison and equality checking for parameter instances, as well as better handling of complex types like arrays, tuples, and dictionaries.

src/BenchmarkDotNet/Parameters · high confidence

Refactored the characteristics system to use a new \`Characteristic\` and \`CharacteristicObject\` hierarchy

The internal structure for managing configuration and state has been refactored. A new \Characteristic\ and \CharacteristicObject\ hierarchy has been introduced, replacing the previous implementation. This change introduces a \CompositeResolver\ and \IResolver\ interface to handle default value resolution, and adds new presenters (\DefaultCharacteristicPresenter\, \FolderCharacteristicPresenter\, etc.) to format output. These changes improve the maintainability and extensibility of the configuration system, though the external API for defining benchmarks remains unchanged.

src/BenchmarkDotNet/Characteristics · high confidence

Removed obsolete benchmark implementations

The Benchmarks project has removed several legacy benchmark classes, including IncrementBenchmark, MultidimensionalArrayBenchmark, StaticFieldBenchmark, and the main Program entry point. This refactoring streamlines the benchmarking suite by eliminating outdated or redundant test cases, likely to make way for the new benchmark programs and settings introduced in the same set of commits.

Benchmarks · medium confidence

Replace SimpleJson with System.Text.Json for serialization

The project has replaced the external SimpleJson library with the built-in System.Text.Json. This introduces new serialization classes (BdnJsonSerializer, BdnJsonSerializerContext, and BdnSimpleJsonSerializer) that handle JSON operations using the modern .NET serialization stack, including custom converters for handling NaN and Infinity values in float and double types.

src/BenchmarkDotNet/Serialization · high confidence

Restructured environment and execution model with new internal data models

The environment information and resolution logic have been restructured into new classes: \BenchmarkEnvironmentInfo\ and \HostEnvironmentInfo\ now encapsulate runtime, GC, and hardware details, while \EnvironmentResolver\, \GcResolver\, and \InfrastructureResolver\ manage characteristic resolution. Additionally, new internal models (\BdnBenchmark\, \BdnEnvironment\, \BdnExecution\, \BdnHostInfo\, \BdnLifecycle\) have been introduced to represent benchmark and host state, supporting a more modular and extensible architecture for environment detection and execution configuration.

src/BenchmarkDotNet/Environments · high confidence

Standardize sample project configuration and structure

The samples directory now includes a new solution file (BenchmarkDotNet.Maui.slnx) that organizes the MAUI sample project alongside the core BenchmarkDotNet projects. Additionally, new Directory.Build.props and Directory.Build.targets files have been added to the samples directory to standardize build properties, such as disabling documentation file generation and packaging, and to import the BenchmarkDotNet targets for builds using ProjectReference.

samples · medium confidence

Test coverage

Add unit tests for HostEnvironmentInfo lazy initialization; Added AssemblyInfo configuration for integration tests; Added AssemblyInfo.cs for integration tests; Added CPU information parsing tests for Windows, Linux, and macOS; Added Mono benchmark and finalizer blocker test infrastructure; Added Perfonar integration tests; Added assembly-level configuration test; Added comprehensive unit tests for BenchmarkDotNet core components; Added in-process emit diff tests; Added integration test for multi-framework benchmark execution; Added integration tests for CPU and PowerShell detection; Added integration tests for JIT optimization states; Added integration tests for custom path DLLs and output file copying; Added integration tests for in-process benchmark emission; Added manual integration tests for dotMemory, dotTrace, and MSBuild arguments; Added serialization tests for disassembler models and summary data; Added test fixtures for Roslyn analyzer validation; Added test infrastructure and mocks for BenchmarkDotNet; Added test infrastructure and scripts for .NET 8.0 and .NET 4.6.1; Added test infrastructure for Perfonar; Added test infrastructure for Roslyn analyzers; Added tests for HostEnvironmentInfo formatting; Added tests for Job ID generation and MSBuild argument escaping; Added tests for Job info in GitHub Markdown disassembly exporter headers; Added tests for Linux OS release parsing and title generation helpers; Added tests for ParamsAllValues and MutatorAttributes; Added tests for Roslyn analyzers detecting incorrect BenchmarkDotNet usage; Added tests for benchmark and job ordering logic; Added tests for benchmark conversion and job grouping logic; Added tests for benchmark validation rules; Added tests for config and job configuration; Added tests for report column handling and formatting; Added tests for the DotMemory diagnoser; Added tests for the async benchmark code fixer; Added tests for version metadata removal; Added tests for virtual machine hypervisor detection; Added unit tests for BenchmarkDotNet column classes; Added unit tests for BenchmarkDotNet engine stages; Added unit tests for LoggerWithPrefix; Added unit tests for OutliersAnalyser and ZeroMeasurementHelper; Added unit tests for Roslyn analyzers; Added unit tests for mathematical and statistical utilities; Added unit tests for the dotTrace diagnoser; Added unit tests for the new ScottPlot-based bar and box plot exporters; Added verification tests for all exporters; Expanded integration test coverage for BenchmarkDotNet.

Dependencies

Update .NET 10 support and modernize project files

The project files have been updated to target .NET 10.0, with the build and sample projects now using the net10.0 target framework. Dependencies such as Cake.Frosting, Docfx.App, and Microsoft.NET.Test.Sdk have been upgraded to their latest versions. Additionally, the solution has been migrated to the modern .csproj format, removing legacy project configurations and unifying the build system.

(dependencies) · high confidence

Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.

How this codebase got here

Baseline

  • First survey — no prior run to compare against. CAI 69.

Lenses

  • Code Health 71
  • Architecture 99
  • Maturity 60
  • Readiness 79
  • Security 80
  • Performance 78

Changes since last survey

  • 300 commits — 223 feature/other, 77 fixes

By area

  • src/BenchmarkDotNet — 161 commits
  • tests/BenchmarkDotNet.IntegrationTests — 22 commits
  • .github/workflows — 19 commits
  • build/BenchmarkDotNet.Build — 13 commits
  • docs/articles — 12 commits
  • tests/BenchmarkDotNet.Tests — 11 commits
  • samples/BenchmarkDotNet.Samples — 8 commits
  • src/BenchmarkDotNet.Analyzers — 8 commits
  • (root) — 5 commits
  • src/BenchmarkDotNet.TestAdapter — 5 commits
  • src/BenchmarkDotNet.Weaver — 5 commits
  • .github/actions — 4 commits
  • src/BenchmarkDotNet.Annotations — 4 commits
  • templates/templates — 4 commits
  • tests/BenchmarkDotNet.Analyzers.Tests — 4 commits
  • tests/BenchmarkDotNet.IntegrationTests.ManualRunning — 4 commits
  • build/common.props — 2 commits
  • tests/BenchmarkDotNet.IntegrationTests.ManualRunning.MultipleFrameworks — 2 commits
  • build/sdk — 1 commit
  • build/versions.txt — 1 commit

Notable commits

  • fix: Allow benchmark methods to use names that are used by code generation templates (fixes #2821) (#2897)
  • fix: Allow filters to filter out every benchmark from a type (Fixes #2860) (#2879)
  • fix: Fix #2581: Copy WarningsAsErrors setting to generated project (#2976)
  • fix: Fix #2751. (#2922)
  • fix: Fix #2793: Use proper FQN in VS Test Explorer to avoid hierarchy split (#2978)
  • fix: Fix #846: Add RAM to environment summary (#3038)
  • fix: Fix JIT detection in new Mono (#3150)
  • fix: Fix MonoAOT file name not provided error during benchmark generation. (#2981)
  • fix: Fix NU1702 (#3217)
  • fix: Fix PathTooLongException by checking max file name component length (#3037)
  • fix: Fix RPlotExporter (#3094) (#3095)
  • fix: Fix SerializedAddressToNameMapping deserialization. (#2925)
  • fix: Fix Thread.TrySetPriority (#3093)
  • fix: Fix WASM restore failing with NETSDK1112 by adding -r browser-wasm to restore command. (#2994)
  • fix: Fix launchIndex in the presence of ExtraRun and in-process SeparateLogic diagnosers.
  • fix: Fix argument
  • fix: Fix async benchmarks with MemoryRandomization (#3103)
  • fix: Fix clrmd version.
  • fix: Fix display strings for multidimensional array parameters (fixes #2891) (#2892)
  • fix: Fix empty property value.
  • …and 280 more

Architecture

  • 0 containers · 1 bounded contexts · 0 dependency edges (baseline)

Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.

Survey your own repository

dotnet/BenchmarkDotNet was measured the same way every project in this corpus was: the same rubric, at a pinned commit, with the result published in full. Point a surveyor at a repository you know and see whether you agree with it.

About this page

  • The score is its most recent published measurement, taken on 5 August 2026 at a pinned commit. It is not a live figure and does not change until the project is measured again.
  • Measured at commit ff369f66cf4cb2be1ea46f91c8dc0d116f4aab8a — the exact code this score is about.
  • Scored under rubric-2026.08.19 — the same rubric and the same method as every other entry in this index.
  • Measured by watchdog.canine.dev using codehealth-analyzer latest.