Skip to content

Repository files navigation

.NET Matrix logo

.NET Matrix

Evidence, not faith.
Choose .NET libraries with confidence using reproducible feature, execution-time and allocation comparisons.

Open the interactive matrix → · How to read the results · Reproduce the results · Link to the matrix

6
CATEGORIES
42
LIBRARIES
67
SCENARIOS

Explore the matrix

Category Leader Libraries Scenarios
CSV Processing Sep 4 10
Dependency Injection Pure.DI 23 15
JSON Serialization System.Text.Json 3 14
Logging Microsoft.Extensions.Logging 5 8
Object Mapping Mapperly 4 10
Validation DataAnnotations 4 10

How to read the results

  • Correctness comes first. Every implementation is checked against the same feature contract before its benchmark results are compared.
  • Lower is better. Overview charts show execution time and allocated memory together.
  • Medals reward consistency. Gold, silver and bronze are awarded to the first three places in every benchmark overview.
  • The Web application is the primary explorer. Use it to select libraries and switch between overview, features, benchmarks and environment details. Chrome and Edge can install it as a desktop application, with a shortcut per category.

The README is a generated snapshot of the reports committed to this repository.

CSV Processing

Sep leads the current rating · 4 libraries · 10 scenarios

Explore interactively →

Rating

# Library 🥇 🥈 🥉 Won
1 Sep 4 gold in Correctness, gold in Read, gold in Throughput, gold in Write
2 Sylvan.Data.Csv 2 2 silver in Throughput, silver in Write, bronze in Correctness, bronze in Read
3 TinyCsvParser 2 1 silver in Correctness, silver in Read, bronze in Throughput
4 CsvHelper 1 bronze in Write

Benchmark overview

Read

CSV Processing Read benchmark overview

More overview charts (3)

Correctness

CSV Processing Correctness benchmark overview

Throughput

CSV Processing Throughput benchmark overview

Write

CSV Processing Write benchmark overview

Compared libraries (4)
CsvHelper logo CsvHelper 33.1.0
A widely used CSV library with record mapping, type conversion, and synchronous and asynchronous readers and writers.
Compare →
Sep logo Sep 0.15.1
A modern SIMD-accelerated separated-values reader and writer with span-based conversion and async enumeration.
Compare →
Sylvan.Data.Csv logo Sylvan.Data.Csv 1.4.4
A high-performance forward-only CSV data reader and writer with strongly typed accessors and asynchronous I/O.
Compare →
TinyCsvParser logo TinyCsvParser 3.0.11
A strongly typed CSV parser with declarative property mapping, custom converters, lazy streaming, and asynchronous readers.
Compare →
Benchmark scenarios (10)

01 · Read Simple Rows

Parses three CSV records and materializes every field as text.

CSV Processing Read Simple Rows benchmark

02 · Read Typed Records

Parses three CSV records and materializes typed scalar values.

CSV Processing Read Typed Records benchmark

03 · Read Large Dataset

Parses and materializes 10,000 typed CSV records.

CSV Processing Read Large Dataset benchmark

04 · Quoted Fields

Parses doubled quote escapes inside quoted CSV fields.

CSV Processing Quoted Fields benchmark

05 · Escaped Delimiters

Parses quoted fields containing a comma or an LF newline.

CSV Processing Escaped Delimiters benchmark

06 · Header Mapping

Maps a reordered CSV header to the correct typed record members.

CSV Processing Header Mapping benchmark

07 · Custom Conversion

Converts sku-NNNN fields to the matrix-owned ProductCode value type.

CSV Processing Custom Conversion benchmark

08 · Streaming Read

Aggregates 10,000 typed rows with forward-only reading and no row materialization.

CSV Processing Streaming Read benchmark

09 · Write Rows

Writes three records with a header to an exact LF-terminated CSV string.

CSV Processing Write Rows benchmark

10 · Async Read

Asynchronously aggregates 10,000 typed CSV rows through the library async API.

CSV Processing Async Read benchmark

Dependency Injection

Pure.DI leads the current rating · 23 libraries · 15 scenarios

Explore interactively →

Rating

# Library 🥇 🥈 🥉 Won
1 Pure.DI 3 gold in Advanced, gold in Basic, gold in Prepare
2 Grace 2 silver in Advanced, silver in Basic
3 MvvmCross 1 silver in Prepare
4 DryIoc 1 bronze in Prepare
5 Singularity 1 bronze in Basic
6 Stashbox 1 bronze in Advanced

Benchmark overview

Basic

Dependency Injection Basic benchmark overview

More overview charts (2)

Advanced

Dependency Injection Advanced benchmark overview

Prepare

Dependency Injection Prepare benchmark overview

Compared libraries (23)
Autofac logo Autofac 9.3.1
A flexible inversion of control container for building extensible .NET applications.
Compare →
Castle Windsor logo Castle Windsor 6.0.0
The Castle Project container, with bound lifestyles and Castle DynamicProxy interception.
Compare →
Catel logo Catel 6.2.0
An MVVM application framework whose service locator and type factory perform constructor injection.
Compare →
DryIoc logo DryIoc 5.4.3
A fast, small and feature-rich container with expression-compiled resolution and rich reuse options.
Compare →
Faster.Ioc logo Faster.Ioc 5.0.0
A minimalistic container focused on the shortest possible resolve path.
Compare →
Grace logo Grace 7.2.1
A container with a fluent registration model, per-object-graph lifestyles and decorator support.
Compare →
Hand-coded logo Hand-coded
Direct dependency injection written in C# without a container.
Compare →
Lamar logo Lamar 16.0.0
The successor to StructureMap, built around runtime code generation.
Compare →
LightInject logo LightInject 7.1.0
A lightweight container with an ultra-small API surface and its own interception package.
Compare →
Maestro logo Maestro 3.6.6
A small container with a fluent configuration API and pluggable activation interceptors.
Compare →
Managed Extensibility Framework 2 logo Managed Extensibility Framework 2 10.0.10
The lightweight Managed Extensibility Framework composition engine shipped as System.Composition.
Compare →
Microsoft Extensions Dependency Injection logo Microsoft Extensions Dependency Injection 10.0.10
The built-in .NET dependency injection container and its service collection abstractions.
Compare →
MvvmCross logo MvvmCross 10.1.2
A cross-platform MVVM framework with its own inversion of control provider.
Compare →
Ninject logo Ninject 3.3.6
A container built around fluent bindings, contextual conditions and pluggable extensions.
Compare →
Pure.DI logo Pure.DI 2.5.2
A compile-time dependency injection framework that generates strongly typed compositions.
Compare →
Simple Injector logo Simple Injector 5.6.0
A fast, opinionated dependency injection library that promotes explicit configuration and maintainable application design.
Compare →
Singularity logo Singularity 0.18.0
An expression-tree based container that validates the whole object graph when the container is built.
Compare →
Spring.NET logo Spring.NET 3.0.3
The Spring.NET application framework and its XML or code configured object factory.
Compare →
Stashbox logo Stashbox 5.20.0
A fast container with per-request lifetimes, conditional registrations and child containers.
Compare →
StructureMap logo StructureMap 4.7.1
A mature container with a fluent registry DSL, nested containers and decorators.
Compare →
Unity logo Unity 5.11.10
The Unity container, offering per-resolve lifetimes and hierarchical child containers.
Compare →
Visual Studio MEF logo Visual Studio MEF 17.13.41
The Visual Studio composition engine, a fast attribute-driven MEF implementation.
Compare →
ZenIoc logo ZenIoc 1.0.1
A tiny container with compiled registrations, named resolution and nested containers.
Compare →
Benchmark scenarios (15)

01 · Singleton

Registers three singleton services and resolves each of them repeatedly. Every resolve of the same service must return the same instance.

Dependency Injection Singleton benchmark

02 · Transient

Registers three transient services and resolves each of them repeatedly. Every resolve must create a new instance, never reusing an earlier one.

Dependency Injection Transient benchmark

03 · PerResolve

Resolves an object graph that asks for the same dependency twice. Both requests inside one resolution share an instance, while the next resolution gets a new one.

Dependency Injection PerResolve benchmark

04 · Scoped

Resolves scoped services inside explicit scopes. One instance per scope, different instances across scopes, and scope-owned disposables are disposed when the scope ends.

Dependency Injection Scoped benchmark

05 · Combined

Resolves three roots that mix singleton and transient dependencies. The singleton is shared across every root while each transient dependency is distinct.

Dependency Injection Combined benchmark

06 · Complex

Registers and resolves three multi-level object graphs, checking that every nested dependency has the expected implementation type and lifetime.

Dependency Injection Complex benchmark

07 · Property

Resolves three roots that carry writable service properties. The container, or its intended property-injection extension, must assign them during activation.

Dependency Injection Property benchmark

08 · Generics

Registers one open generic service mapping and resolves roots closed over int, float and object. Registering every closed type separately does not count.

Dependency Injection Generics benchmark

09 · IEnumerable

Injects a sequence of five plugin implementations and requires it to be genuinely lazy: nothing is created until enumeration, and every enumeration yields new transients.

Dependency Injection IEnumerable benchmark

10 · Array

Resolves three roots that materialise their injected sequence of five plugins into an array while the root is being activated.

Dependency Injection Array benchmark

11 · Conditional

Gives each of three consumers a different implementation of one contract, chosen through the metadata, key, predicate or consumer-context mechanism of the library.

Dependency Injection Conditional benchmark

12 · Child Container

Creates a real nested child container that inherits the registrations of its parent and can add or override them without changing the parent.

Dependency Injection Child Container benchmark

13 · Interception With Proxy

Resolves a service through the interception or activation extension point of the library. The result must be a proxy whose interceptor proceeds to the real target.

Dependency Injection Interception With Proxy benchmark

14 · Prepare And Register

Measures creating the container and registering the whole prescribed graph, without resolving anything from it.

Dependency Injection Prepare And Register benchmark

15 · Prepare And Register And Simple Resolve

Measures the same setup as Prepare And Register, followed by a single resolve of one singleton root.

Dependency Injection Prepare And Register And Simple Resolve benchmark

JSON Serialization

System.Text.Json leads the current rating · 3 libraries · 14 scenarios

Explore interactively →

Rating

# Library 🥇 🥈 🥉 Won
1 System.Text.Json 5 1 gold in Advanced, gold in Basic, gold in Collections, gold in Nested, gold in Stream, silver in Prepare
2 ServiceStack.Text 1 4 gold in Prepare, silver in Basic, silver in Collections, silver in Nested, silver in Stream
3 Newtonsoft.Json 1 5 silver in Advanced, bronze in Basic, bronze in Collections, bronze in Nested, bronze in Prepare, bronze in Stream

Benchmark overview

Basic

JSON Serialization Basic benchmark overview

More overview charts (5)

Nested

JSON Serialization Nested benchmark overview

Collections

JSON Serialization Collections benchmark overview

Advanced

JSON Serialization Advanced benchmark overview

Stream

JSON Serialization Stream benchmark overview

Prepare

JSON Serialization Prepare benchmark overview

Compared libraries (3)
Newtonsoft.Json logo Newtonsoft.Json 13.0.4
A mature JSON framework for .NET with configurable contracts, converters, and streaming readers and writers.
Compare →
ServiceStack.Text logo ServiceStack.Text 10.0.8
A high-performance text library with typed JSON, stream, collection, and type-specific serialization APIs.
Compare →
System.Text.Json logo System.Text.Json
The reflection-based and source-generated JSON serializer included with .NET.
Compare →
Benchmark scenarios (14)

01 · Serialize Simple Object

Serializes one scalar object to a compact JSON string.

JSON Serialization Serialize Simple Object benchmark

02 · Deserialize Simple Object

Deserializes one compact JSON object and validates every scalar member.

JSON Serialization Deserialize Simple Object benchmark

03 · Serialize Nested Object

Serializes an order, customer, and address object graph.

JSON Serialization Serialize Nested Object benchmark

04 · Deserialize Nested Object

Deserializes and materializes an order, customer, and address object graph.

JSON Serialization Deserialize Nested Object benchmark

05 · Serialize Collection

Serializes three ordered objects to a compact JSON array.

JSON Serialization Serialize Collection benchmark

06 · Deserialize Collection

Deserializes a compact JSON array to three ordered objects.

JSON Serialization Deserialize Collection benchmark

07 · Serialize Dictionary

Serializes three ordered string and integer entries to a JSON object.

JSON Serialization Serialize Dictionary benchmark

08 · Deserialize Dictionary

Deserializes a JSON object to three ordinal string and integer entries.

JSON Serialization Deserialize Dictionary benchmark

09 · Enum Round Trip

Serializes an enum as its string name and deserializes it back.

JSON Serialization Enum Round Trip benchmark

10 · Custom Converter Round Trip

Serializes a strongly typed identifier as a JSON string and deserializes it back.

JSON Serialization Custom Converter Round Trip benchmark

11 · Polymorphic Round Trip

Round-trips a base-type collection through safe cat and dog discriminators.

JSON Serialization Polymorphic Round Trip benchmark

12 · UTF-8 Stream Round Trip

Serializes a simple object to a new UTF-8 memory stream and deserializes it back.

JSON Serialization UTF-8 Stream Round Trip benchmark

13 · Source Generation Round Trip

Round-trips a simple object with compile-time generated JSON metadata.

JSON Serialization Source Generation Round Trip benchmark

14 · Prepare Serializer

Creates fresh serializer settings and explicit type metadata without serializing data.

JSON Serialization Prepare Serializer benchmark

Logging

Microsoft.Extensions.Logging leads the current rating · 5 libraries · 8 scenarios

Explore interactively →

Rating

# Library 🥇 🥈 🥉 Won
1 Microsoft.Extensions.Logging 2 gold in Core, gold in Structured
2 Serilog 1 2 gold in Prepare, bronze in Core, bronze in Structured
3 NLog 3 silver in Core, silver in Prepare, silver in Structured
4 log4net 1 bronze in Prepare

Benchmark overview

Core

Logging Core benchmark overview

More overview charts (2)

Structured

Logging Structured benchmark overview

Prepare

Logging Prepare benchmark overview

Compared libraries (5)
log4net logo log4net 3.3.2
A mature Apache logging framework with hierarchical repositories, contextual properties, layouts, and appenders.
Compare →
Microsoft.Extensions.Logging logo Microsoft.Extensions.Logging 10.0.10
The standard .NET logging abstraction and logger factory with providers, filtering, structured state, and scopes.
Compare →
NLog logo NLog 6.1.4
A configurable logging platform with structured events, scope context, targets, layouts, and asynchronous wrappers.
Compare →
Serilog logo Serilog 4.4.0
A structured event logger with message templates, contextual enrichment, and a broad sink ecosystem.
Compare →
ZLogger logo ZLogger 2.5.10
A source-generated and interpolated-string logger built on Microsoft.Extensions.Logging with UTF-8 and processor APIs.
Compare →
Benchmark scenarios (8)

01 · Disabled Log

Submits an Information event to a logger whose minimum level is Warning.

Logging Disabled Log benchmark

02 · Simple Message

Delivers one literal Information message to an in-memory sink.

Logging Simple Message benchmark

03 · Structured Properties

Delivers one event with independently queryable OrderId and ElapsedMs properties.

Logging Structured Properties benchmark

04 · Exception

Delivers one Error event retaining the original exception metadata.

Logging Exception benchmark

05 · Scope Or Context

Creates a temporary RequestId context and captures it on one event.

Logging Scope Or Context benchmark

06 · Template Rendering

Formats amount 12.5 and customer Ada through the logger template API.

Logging Template Rendering benchmark

07 · Buffered Logging

Enqueues one event to a library-provided async or buffering wrapper and validates delivery after flush.

Logging Buffered Logging benchmark

08 · Prepare Logger

Creates, verifies, and releases one Information-enabled logger with an in-memory sink.

Logging Prepare Logger benchmark

Object Mapping

Mapperly leads the current rating · 4 libraries · 10 scenarios

Explore interactively →

Rating

# Library 🥇 🥈 🥉 Won
1 Mapperly 3 gold in Advanced, gold in Basic, gold in Prepare
2 Mapster 2 1 silver in Advanced, silver in Basic, bronze in Prepare
3 AutoMapper 1 2 silver in Prepare, bronze in Advanced, bronze in Basic

Benchmark overview

Basic

Object Mapping Basic benchmark overview

More overview charts (2)

Advanced

Object Mapping Advanced benchmark overview

Prepare

Object Mapping Prepare benchmark overview

Compared libraries (4)
AutoMapper logo AutoMapper 16.2.0
A convention-based object-object mapper with runtime configuration and compiled mapping plans.
Compare →
Hand-coded logo Hand-coded
Direct object mapping written in C# without a mapping library.
Compare →
Mapperly logo Mapperly 4.3.1
A source generator that creates readable object mapping code at compile time.
Compare →
Mapster logo Mapster 10.0.11
An object mapper with runtime configuration, expression compilation, and projection support.
Compare →
Benchmark scenarios (10)

01 · Simple Object

Maps one object with scalar values to a newly allocated destination object.

Object Mapping Simple Object benchmark

02 · Nested Object

Maps an order with nested customer and address objects to a new destination graph.

Object Mapping Nested Object benchmark

03 · Collection

Maps an array of 100 objects while preserving count, order and member values.

Object Mapping Collection benchmark

04 · Flattening

Maps nested customer values into a flat order summary through member-path configuration.

Object Mapping Flattening benchmark

05 · Map To Existing

Overwrites a supplied destination object and returns that same instance.

Object Mapping Map To Existing benchmark

06 · Null Handling

Preserves null text, nested object and collection members in the destination.

Object Mapping Null Handling benchmark

07 · Custom Conversion

Maps string values through registered code and invariant decimal conversions.

Object Mapping Custom Conversion benchmark

08 · Polymorphic Mapping

Maps a base array containing cats and dogs to matching destination runtime types.

Object Mapping Polymorphic Mapping benchmark

09 · Prepare Configuration

Creates the complete mapper configuration and eagerly prepares its runtime mapping plans.

Object Mapping Prepare Configuration benchmark

10 · Prepare And Simple Map

Creates the complete mapper configuration and maps one simple object.

Object Mapping Prepare And Simple Map benchmark

Validation

DataAnnotations leads the current rating · 4 libraries · 10 scenarios

Explore interactively →

Rating

# Library 🥇 🥈 🥉 Won
1 DataAnnotations 2 2 gold in Prepare, gold in Rules, bronze in Basic, bronze in Object Graph
2 Microsoft.Extensions.Validation 1 2 gold in Basic, silver in Object Graph, silver in Prepare
3 MiniValidation 1 1 1 gold in Object Graph, silver in Basic, bronze in Prepare
4 FluentValidation 1 silver in Rules

Benchmark overview

Basic

Validation Basic benchmark overview

More overview charts (3)

Object Graph

Validation Object Graph benchmark overview

Rules

Validation Rules benchmark overview

Prepare

Validation Prepare benchmark overview

Compared libraries (4)
DataAnnotations logo DataAnnotations
The validation attributes and validation APIs included with the .NET framework.
Compare →
FluentValidation logo FluentValidation 12.1.1
A strongly typed validation library with fluent rules, nested validators, cascade modes, and asynchronous validation.
Compare →
Microsoft.Extensions.Validation logo Microsoft.Extensions.Validation 10.0.10
The official source-generated validation infrastructure for DataAnnotations-based object graph validation outside ASP.NET Core.
Compare →
MiniValidation logo MiniValidation 0.10.0
A minimal DataAnnotations-based validator with recursive object graph traversal and cycle detection.
Compare →
Benchmark scenarios (10)

01 · Valid Object

Validates one object whose scalar properties satisfy every rule.

Validation Valid Object benchmark

02 · Single Failure

Validates one object and returns its single property failure.

Validation Single Failure benchmark

03 · Multiple Failures

Validates one object and materializes three independent property failures.

Validation Multiple Failures benchmark

04 · Nested Object

Traverses a nested object and reports the complete failing property path.

Validation Nested Object benchmark

05 · Collection

Traverses three collection elements and reports an indexed failure path.

Validation Collection benchmark

06 · Conditional Rule

Applies a tax ID rule only when the input represents a business.

Validation Conditional Rule benchmark

07 · Custom Rule

Applies a custom predicate that accepts only even integer codes.

Validation Custom Rule benchmark

08 · Stop On First Failure

Stops validation after the first failing rule in the declared order.

Validation Stop On First Failure benchmark

09 · Async Validation

Runs a deterministic asynchronous availability rule through the library async API.

Validation Async Validation benchmark

10 · Prepare Validator

Creates the complete scalar validator or rule graph without validating an input.

Validation Prepare Validator benchmark

Reproduce the results

Environment requirements

The complete workflow requires:

  • a 64-bit operating system supported by the .NET 10 SDK;
  • the .NET 10 SDK available as dotnet on PATH;
  • access to the configured NuGet sources on the first run, or a populated local package cache;
  • a writable repository checkout and several GB of free space for build, BenchmarkDotNet, report, and Web artifacts;
  • at least 8 GB of RAM as a practical minimum.

For meaningful performance comparisons, run on an otherwise idle machine, connected to power, without a debugger, with a fixed performance-oriented power profile. Do not combine results produced by different frameworks, runtimes, operating systems, architectures, or processors without reviewing the recorded benchmark environment.

Run the complete reproducible workflow:

dotnet run --project .\build -- reproduce

The target validates and benchmarks every library, regenerates reports, charts, metadata, README, and Rider configurations, and starts the local Web application on an automatically selected available port. Use --no-browser to suppress automatic browser opening. Press Ctrl+C to stop the local application.

To use the reports already on disk and go directly to artifact generation and the local application:

dotnet run --project .\build -- reproduce --skip-benchmarks

Child-process output is saved under artifacts/logs; the console shows concise progress and prints the relevant log tail if an operation fails.

The Run .NET Matrix Reports GitHub Actions workflow produces one matrix-reports archive containing every category report, the raw BenchmarkDotNet evidence, summaries, a manifest, and SHA-256 checksums. Download that archive and import the complete verified snapshot manually with:

dotnet run --project .\build -- import-reports --archive .\matrix-reports.zip

Repository report JSON files and their evidence are updated under reports from the same archive. Evidence is committed with the report, so a Git tag preserves the measurements and their provenance together.

To regenerate source-controlled artifacts without starting the local application:

dotnet run --project .\build -- finalize-commit

Running the complete benchmark matrix can take a long time. Use dotnet run --project .\build -- --help to find commands for a single category or library.

Link to a category or a library

The application reads three optional query parameters, so a page about a library can link straight to the relevant comparison instead of the front page:

Link Opens
https://matrix.dev-team.org/ the default category, newest reports
https://matrix.dev-team.org/?category=csv-processing that category
https://matrix.dev-team.org/?library=CsvHelper the library overview, in its own category
https://matrix.dev-team.org/?version=latest&library=CsvHelper the same overview, newest release named explicitly

The three are independent and combine freely; the links in the tables above are the same thing with the values filled in.

category

Accepts the category id or its displayed name, for example ?category=csv-processing. Matching ignores case, spaces and punctuation.

library

Accepts the library id, its displayed name or its NuGet package id, and finds the category on its own, so ?library=CsvHelper needs no category beside it. Add category only to break a tie between two categories that use the same library id. The library overview opens as a dialog over the matrix.

version

Pins the reports to one release. It takes a release name exactly as the picker shows it, for example ?version=1.2.0, or the word latest. Unlike the other two, the value is matched exactly: dropping punctuation would make 1.2.3 and 12.3 indistinguishable.

Leave it out to follow every new release — a link without it always shows the newest reports, which is what a page about a library normally wants. Use it when the link has to keep showing the numbers it was written against, for example next to a quoted result in an article.

The release picker in the application writes the parameter into the address, and the copy buttons follow the same rule: the release appears in the copied link only while an older one is being viewed.

An unknown value of any of the three falls back to the default view rather than to an error, so a typo in a link published elsewhere still lands the reader in the matrix.

Releases

Contributors

Languages