Section 6 of 6
Profiling Tools
🎯 What You'll Learn
- MiniProfiler
- Application Insights
- dotnet-trace
- BenchmarkDotNet
- SQL Server Profiler
MiniProfiler
Lightweight profiler for ASP.NET Core applications.
Install Package
Bash
dotnet add package MiniProfiler.AspNetCore.Mvc
dotnet add package MiniProfiler.EntityFrameworkCore
Program.cs
C#
builder.Services.AddMiniProfiler(options =>
{
options.RouteBasePath = "/profiler";
}).AddEntityFramework();
var app = builder.Build();
app.UseMiniProfiler();
_Layout.cshtml
HTML
<head>
<mini-profiler />
</head>
Application Insights
Azure's application performance management service.
Install Package
Bash
dotnet add package Microsoft.ApplicationInsights.AspNetCore
Program.cs
C#
builder.Services.AddApplicationInsightsTelemetry();
appsettings.json
JSON
{
"ApplicationInsights": {
"InstrumentationKey": "your-key-here"
}
}
dotnet-trace
Command-line tool for collecting performance traces.
Install Tool
Bash
dotnet tool install --global dotnet-trace
Collect Trace
Bash
# List processes
dotnet-trace ps
# Collect trace
dotnet-trace collect --process-id <PID>
BenchmarkDotNet
Powerful benchmarking library for .NET.
Install Package
Bash
dotnet add package BenchmarkDotNet
Benchmark Example
C#
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Running;
[MemoryDiagnoser]
public class ProductBenchmarks
{
private List<Product> _products;
[GlobalSetup]
public void Setup()
{
_products = Enumerable.Range(1, 1000)
.Select(i => new Product { Id = i, Name = $"Product {i}" })
.ToList();
}
[Benchmark]
public List<Product> FilterWithWhere()
{
return _products.Where(p => p.Id > 500).ToList();
}
[Benchmark]
public List<Product> FilterWithFor()
{
var result = new List<Product>();
for (int i = 0; i < _products.Count; i++)
{
if (_products[i].Id > 500)
result.Add(_products[i]);
}
return result;
}
}
// Run benchmarks
BenchmarkRunner.Run<ProductBenchmarks>();
SQL Server Profiler
Monitor SQL queries generated by EF Core.
Enable Sensitive Data Logging
C#
builder.Services.AddDbContext<InvenTrackDbContext>(options =>
{
options.UseSqlServer(connectionString)
.EnableSensitiveDataLogging() // Development only!
.LogTo(Console.WriteLine, LogLevel.Information);
});
Performance Checklist
- Cache frequently accessed data: Use in-memory or distributed caching
- Use async/await: For I/O operations
- Optimize queries: Use Include, AsNoTracking, projections
- Enable response caching: For static content
- Profile regularly: Use MiniProfiler or Application Insights
- Monitor SQL: Check generated queries
- Benchmark critical paths: Use BenchmarkDotNet
Key Takeaways
- MiniProfiler: Lightweight profiling for dev
- Application Insights: Production monitoring
- dotnet-trace: Performance trace collection
- BenchmarkDotNet: Micro-benchmarking
- SQL logging: Monitor EF Core queries
- Profile early: Find bottlenecks before production
🎉 Part XVII Complete!
Congratulations! You've completed Part XVII: Performance & Caching. You now understand:
- ✅ In-memory caching (IMemoryCache, expiration, eviction)
- ✅ Distributed caching (Redis, SQL Server, serialization)
- ✅ Response caching ([ResponseCache], cache profiles)
- ✅ Async best practices (async all the way, avoid blocking)
- ✅ EF Core performance (Include, AsNoTracking, projections)
- ✅ Profiling tools (MiniProfiler, Application Insights, BenchmarkDotNet)
Your applications are now fast and scalable! ⚡