Benchmarking BenchmarkDotNetillä
Kirjoittakaa tarkkoja mikrovertailuja BenchmarkDotNetillä, analysoikaa läpimenoa ja allokointeja sekä välttäkää yleiset sudenkuopat.
Benchmarking BenchmarkDotNetillä on ilmainen C# Academy-oppitunti CoddyKitissä. Tämä on oppitunti 4/4. Voit lukea koko oppitunnin alta ilmaiseksi ja harjoitella sen jälkeen käytännössä selaimessa sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla. Oppitunti kuuluu C# Academy-oppimispolkuun, ja edistymisesi synkronoituu verkon ja CoddyKit-sovelluksen välillä. C# Academy-kurssilla on yhteensä 4 oppituntia.
Miksi BenchmarkDotNet?
Mikrobenchmarkkaus on yllättävän vaikeaa: JIT:n lämmitys, roskienkeruun tauot, suorittimen välimuistit ja käyttöjärjestelmän ajoitus aiheuttavat kaikki kohinaa. BenchmarkDotNet käsittelee kaiken tämän automaattisesti ja tuottaa tilastollisesti luotettavia tuloksia.
Asennus ja ensimmäinen suorituskykymittaus
Lisätkää NuGet-paketti, luokaa luokka, jossa on [Benchmark]-menetelmiä, ja suorittakaa se komennolla BenchmarkRunner.Run. Suorittakaa suorituskykymittaukset aina Release-tilassa.
// dotnet add package BenchmarkDotNet
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Running;
[MemoryDiagnoser] // report allocations
[RankColumn] // rank methods by speed
public class StringBenchmarks
{
[Benchmark(Baseline = true)]
public string Concatenation()
{
var s = "";
for (int i = 0; i < 100; i++) s += i;
return s;
}
[Benchmark]
public string StringBuilder()
{
var sb = new System.Text.StringBuilder();
for (int i = 0; i < 100; i++) sb.Append(i);
return sb.ToString();
}
}
// Program.cs (must run as Release):
BenchmarkRunner.Run<StringBenchmarks>();Tulostaulukon lukeminen
BenchmarkDotNet tulostaa tulostaulukon, jossa ovat keskimääräinen aika, virhe, keskihajonta, suhde ja muistin varaus. Näin tulkitsette jokaisen sarakkeen.
// Example output:
// | Method | Mean | Error | StdDev | Ratio | Alloc |
// |-------------- |---------:|--------:|--------:|------:|------:|
// | Concatenation | 4,210 ns | 81 ns | 76 ns | 1.00 | 6.4KB |
// | StringBuilder | 312 ns | 4 ns | 4 ns | 0.07 | 1.6KB |
// Mean: average time per operation
// Error: half of 99.9% confidence interval
// StdDev: standard deviation — high value = noisy environment
// Ratio: relative to Baseline=true method (1.00)
// Alloc: managed heap allocated per operation
// Rule of thumb:
// Error should be < 5% of Mean for reliable results
// Run on an isolated machine (no background tasks)Parametrisoidut suorituskykymittaukset
Käyttäkää [Params]-attribuuttia suorituskykymittauksen suorittamiseen useilla syöteko'oilla. BenchmarkDotNet suorittaa kaikki yhdistelmät ja luo jokaiselle parametriarvolle oman rivin.
[MemoryDiagnoser]
public class SearchBenchmarks
{
[Params(10, 100, 1000, 10000)]
public int N;
private int[] _data = Array.Empty<int>();
[GlobalSetup]
public void Setup()
=> _data = Enumerable.Range(0, N).ToArray();
[Benchmark]
public bool LinearSearch()
=> Array.IndexOf(_data, N - 1) >= 0;
[Benchmark]
public bool BinarySearch()
=> Array.BinarySearch(_data, N - 1) >= 0;
}Valmistelu ja siivous
Käyttäkää elinkaarimääritteitä kertaluonteisen valmistelun tai iteraatiokohtaisen valmistelun ja siivouksen suorittamiseen. Näin valmistelun kustannus jää mitatun suorituskykymittausajan ulkopuolelle.
[MemoryDiagnoser]
public class DbQueryBenchmarks
{
private NpgsqlConnection _conn = null!;
private NpgsqlCommand _cmd = null!;
[GlobalSetup] // runs once before all benchmarks
public void Setup()
{
_conn = new NpgsqlConnection("...");
_conn.Open();
_cmd = new NpgsqlCommand("SELECT id FROM orders LIMIT 100", _conn);
}
[IterationSetup] // runs before EACH benchmark iteration
public void IterationSetup() { /* per-iteration prep */ }
[Benchmark]
public int QueryOrders() => (int)_cmd.ExecuteScalar()!;
[GlobalCleanup] // runs once after all benchmarks
public void Cleanup() { _cmd.Dispose(); _conn.Dispose(); }
}Muistidiagnostiikka
[MemoryDiagnoser] raportoi hallitun keon varaukset operaatiota kohti. Yhdistäkää se [GcForce]-asetuksiin roskienkeruun toiminnan hallitsemiseksi suorituskykymittausten aikana.
[MemoryDiagnoser] // adds Alloc column to results
public class AllocationBenchmarks
{
[Benchmark]
public int[] AllocateArray() => new int[1000];
[Benchmark]
public Span<int> UseStackalloc()
{
Span<int> span = stackalloc int[1000];
return span; // WARN: for illustration; don't return stackalloc
}
[Benchmark]
public int[] ArrayPoolRent()
{
var arr = System.Buffers.ArrayPool<int>.Shared.Rent(1000);
System.Buffers.ArrayPool<int>.Shared.Return(arr);
return arr;
}
}Diagnosoijat: ETW ja disassembly
BenchmarkDotNet tukee useita diagnosoijia. DisassemblyDiagnoser näyttää todellisen natiivin assembly-koodin, joten se sopii erinomaisesti JIT-optimointien tarkistamiseen.
using BenchmarkDotNet.Diagnosers;
[DisassemblyDiagnoser( // show generated ASM
maxDepth: 2,
printSource: true,
exportGithubMarkdown: true)]
[MemoryDiagnoser]
public class VectorizationBenchmarks
{
private float[] _data = new float[1024];
[Benchmark]
public float SumScalar()
{
float sum = 0;
foreach (var v in _data) sum += v;
return sum;
}
[Benchmark]
public float SumVectorized()
=> System.Numerics.Vector<float>.Count > 1
? VectorSum(_data)
: SumScalar();
}Job-määritykset
Jobit hallitsevat suorituskykymittauksen suoritusympäristöä: lämmittelyiteraatioiden määrää, kutsujen määrää iteraatiota kohden, .NET-suoritusympäristön versiota ja JIT-asetuksia. Käyttäkää esimääritettyjä tai mukautettuja jobeja.
using BenchmarkDotNet.Jobs;
// Compare JIT vs Native AOT performance:
[SimpleJob(RuntimeMoniker.Net90)] // .NET 9 JIT
[SimpleJob(RuntimeMoniker.NativeAot90)] // .NET 9 AOT
[MemoryDiagnoser]
public class RuntimeComparison
{
[Benchmark]
public string SerializeJson()
{
var obj = new { Name = "Alice", Age = 30 };
return System.Text.Json.JsonSerializer.Serialize(obj);
}
}
// Custom job for more warmup:
[Config(typeof(MyConfig))]
public class PreciseBenchmarks
{
private class MyConfig : ManualConfig
{
public MyConfig()
=> AddJob(Job.Default.WithWarmupCount(5).WithIterationCount(20));
}
}Tulosten vieminen
BenchmarkDotNet vie tuloksia useissa muodoissa: Markdown-muodossa (GitHub PR:iä varten), CSV-muodossa (taulukkolaskentaa varten), JSON-muodossa ja HTML-kaavioina. Vientiasetukset määritetään job-määrityksissä.
using BenchmarkDotNet.Exporters;
using BenchmarkDotNet.Exporters.Csv;
[Config(typeof(ExportConfig))]
public class MyBenchmarks { /* ... */ }
public class ExportConfig : ManualConfig
{
public ExportConfig()
{
AddExporter(MarkdownExporter.GitHub);
AddExporter(CsvExporter.Default);
AddExporter(HtmlExporter.Default);
// Results in: BenchmarkDotNet.Artifacts/results/
}
}
// CLI usage to run specific benchmarks:
// dotnet run -c Release -- --filter "*StringBenchmarks*"
// dotnet run -c Release -- --list all (list all benchmarks)Tosielämän esimerkki: optimointia ennen ja sen jälkeen
BenchmarkDotNetin käyttäminen suorituskykyoptimoinnin vahvistamiseen vertaamalla naiivia, poolattua ja Span-pohjaista lähestymistapaa.
[MemoryDiagnoser]
[RankColumn]
public class ParsingBenchmarks
{
private const string Input = "2025-06-15T08:30:00Z";
[Benchmark(Baseline = true)]
public DateTime ParseViaString()
=> DateTime.Parse(Input);
[Benchmark]
public DateTime ParseExact()
=> DateTime.ParseExact(Input,
"yyyy-MM-ddTHH:mm:ssZ",
System.Globalization.CultureInfo.InvariantCulture);
[Benchmark]
public bool TryParse()
=> DateTime.TryParseExact(Input.AsSpan(),
"yyyy-MM-ddTHH:mm:ssZ",
System.Globalization.CultureInfo.InvariantCulture,
System.Globalization.DateTimeStyles.None,
out _);
}Pikatarkistus
Miksi BenchmarkDotNet-suorituskykymittaukset on suoritettava komennolla dotnet run -c Release?
Kertaus: suorituskyvyn mittaaminen BenchmarkDotNetillä
Keskeiset opit:
- Asenna NuGetin kautta, merkitse menetelmät
[Benchmark]-attribuutilla ja suorita komennolladotnet run -c Release [MemoryDiagnoser]: lisää varauksia sisältävän sarakkeen;[RankColumn]: järjestää tulokset nopeuden mukaan[Params]: suorita mittaukset useilla syöteko'oilla algoritmisen vaativuuden selvittämiseksi[GlobalSetup]/[GlobalCleanup]: kertaluonteinen valmistelu mitatun ajan ulkopuolella[DisassemblyDiagnoser]: tarkastele tuotettua natiivikoodia JIT-optimointien vahvistamiseksi- Käyttäkää jobeja vertaillaksenne .NET 9:n JIT:iä, Native AOT:tä ja erilaisia iteraatiomääriä
Opi C# tekoälytuutorin avulla — ilmaiseksi
Kirjoita ja suorita oikeaa koodia selaimessa, saa välitöntä apua tekoälytuutorilta ympäri vuorokauden ja jatka siitä, mihin jäit, verkossa tai sovelluksessa.
- Kurssit
- 93
- Oppitunnit
- 346
Usein kysytyt kysymykset
Onko oppitunti ”Benchmarking BenchmarkDotNetillä” ilmainen?
Kyllä – oppitunnin ”Benchmarking BenchmarkDotNetillä” koko tekstin voi lukea täällä verkossa ilmaiseksi. Jos haluat harjoitella interaktiivisesti sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla sekä avata koko C# Academy-kurssin, päivitä CoddyKit PROhon. C# Academy-kurssilla on yhteensä 4 oppituntia.
Mitä opin oppitunnilla ”Benchmarking BenchmarkDotNetillä”?
Kirjoittakaa tarkkoja mikrovertailuja BenchmarkDotNetillä, analysoikaa läpimenoa ja allokointeja sekä välttäkää yleiset sudenkuopat. Harjoittelet C# Academy-aihetta koodilla, jonka suoritat suoraan selaimessa. Ympäri vuorokauden käytettävissä oleva tekoälytuutori vastaa kysymyksiisi oppitunnin aikana.
Tarvitsenko kokemusta aloittaakseni C# Academy-opiskelun?
Aiempi kokemus ei ole tarpeen. CoddyKitin C# Academy-oppimispolku sopii vasta-alkajista edistyneisiin, joten voit aloittaa tästä tai alusta ja edetä omaan tahtiisi. Tämä on oppitunti 4/4.
Kuinka kauan ”Benchmarking BenchmarkDotNetillä”-oppitunnin suorittaminen kestää?
Useimmat CoddyKitin oppitunnit kestävät noin 5–10 minuuttia. Jokainen oppitunti on lyhyt ja interaktiivinen, joten edistyt tasaisesti ja voit jatkaa siitä, mihin jäit – sekä verkossa että sovelluksessa.
Voinko kirjoittaa ja suorittaa koodia tällä C# Academy-oppitunnilla?
Kyllä. Jokainen C# Academy-oppitunti sisältää sisäänrakennetun koodieditorin, joten voit kirjoittaa ja suorittaa oikeaa koodia suoraan selaimessa ja saada välitöntä palautetta tekoälyltä – paikallista asennusta ei tarvita.
Kaikki tämän kurssin oppitunnit
- Native AOT -käännös
- Trimmaus ja reflektion rajoitukset
- ReadyToRun ja tasokohtainen käännös
- Benchmarking BenchmarkDotNetillä