惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

T
The Exploit Database - CXSecurity.com
F
Fortinet All Blogs
U
Unit 42
F
Full Disclosure
雷峰网
雷峰网
博客园 - 司徒正美
云风的 BLOG
云风的 BLOG
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
T
Tailwind CSS Blog
The Cloudflare Blog
Last Week in AI
Last Week in AI
罗磊的独立博客
D
DataBreaches.Net
C
Check Point Blog
www.infosecurity-magazine.com
www.infosecurity-magazine.com
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
O
OpenAI News
C
CXSECURITY Database RSS Feed - CXSecurity.com
aimingoo的专栏
aimingoo的专栏
S
Security @ Cisco Blogs
大猫的无限游戏
大猫的无限游戏
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
S
SegmentFault 最新的问题
NISL@THU
NISL@THU
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
The Hacker News
The Hacker News
Webroot Blog
Webroot Blog
Security Latest
Security Latest
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
Google DeepMind News
Google DeepMind News
酷 壳 – CoolShell
酷 壳 – CoolShell
N
News | PayPal Newsroom
P
Proofpoint News Feed
B
Blog RSS Feed
MongoDB | Blog
MongoDB | Blog
C
Cybersecurity and Infrastructure Security Agency CISA
N
News and Events Feed by Topic
Google Online Security Blog
Google Online Security Blog
H
Help Net Security
Spread Privacy
Spread Privacy
T
Threat Research - Cisco Blogs
GbyAI
GbyAI
I
Intezer
Application and Cybersecurity Blog
Application and Cybersecurity Blog
M
MIT News - Artificial intelligence
Vercel News
Vercel News
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
IT之家
IT之家
MyScale Blog
MyScale Blog
腾讯CDC

博客园 - Charltsing

C# 预处理器指令语言 - 完整语法速查 LoggerMessage:编写高性能的 .NET 日志 PDFImageViewer v2.1 PDF查看图像和无损导出工具,一键转换单图PDF为JBig2黑白PDF。兼谈PDF内嵌图像。 PDF的色彩空间 PDFontFixer v1.5 免费版,解决PDF文档复制粘贴乱码的问题,修复PDF文档字体的Unicode映射。 为什么 PDF 编辑这么难? Unicode、UTF-8、UTF-16 如何直接编辑Github的Readme.md文件 自动导入工程项目属性,Directory.Build.props 和 Directory.Build.targets 新版 C# 高效率编程指南 C# 内联数组(Inline Array):高性能数组的新选择 如何在 .NET 中使用 SIMD .NET异步编程进阶:从语法糖到高性能架构的核心突破 C# 中的安全零拷贝 使用UnsafeAccessor 访问私有字段 C# 12与.NET 8实战指南:20个提升代码质量的最佳实践 C# Net9的模块初始化器(Module Initializer) ECMA-335 CLI 规范附录 C#中避免GC压力和提高性能的8种技术 函数内联 硬件内在函数 官方:oPDF v2.1免费版,专业的PDF水印分析处理工具,无损去除水印,通杀八类PDF水印。它是PDFCommander 万能PDF水印删除工具的升级版。 C#自动引用Debug | Release版本的dll
25 个使用.NET 10 的性能技巧
Charltsing · 2026-03-31 · via 博客园 - Charltsing

O .NET 10 traz melhorias significativas de performance, mas conhecer as técnicas certas faz toda a diferença. Este artigo reúne 25 dicas práticas para extrair o máximo de suas aplicações.
.NET 10 带来了显著的性能提升,但掌握正确的技巧才能发挥最大效果。本文汇集了 25 条实用技巧,帮助您最大限度地提升应用程序性能。

1. Prefira Span para manipulação de dados em memória
1. 在内存中处理数据时优先选择 Span

Span<T> permite trabalhar com fatias de memória sem alocações adicionais. Ideal para parsing e manipulação de strings ou arrays.
Span<T> 允许在不进行额外分配的情况下处理内存片段。非常适合解析和字符串或数组的操作。

// Evite: cria substring (alocação)
string texto = "nome:valor";
string valor = texto.Substring(5);

// Prefira: zero alocações
ReadOnlySpan<char> span = texto.AsSpan();
ReadOnlySpan<char> valorSpan = span.Slice(5);

O ganho é especialmente relevante em loops ou operações de alto throughput, onde cada alocação evitada reduz a pressão sobre o Garbage Collector.
在循环或高吞吐量操作中,这种优势尤其明显,因为每次避免的分配都会减轻垃圾回收器的压力。

2. Use FrozenDictionary e FrozenSet para dados imutáveis
2. 使用 FrozenDictionary 和 FrozenSet 处理不可变数据

Introduzidas no .NET 8 e otimizadas no .NET 10, as coleções "frozen" são ideais para dados que não mudam após a inicialização.
在.NET 8 中引入并在.NET 10 中优化的"冻结"集合非常适合初始化后不会更改的数据。

using System.Collections.Frozen;

// Dados de configuração que nunca mudam
var statusCodes = new Dictionary<int, string>
{
    [200] = "OK",
    [404] = "Not Found",
    [500] = "Internal Server Error"
}.ToFrozenDictionary();

// Lookup significativamente mais rápido que Dictionary regular
var descricao = statusCodes[200];

O custo de criação é maior, mas as leituras subsequentes são significativamente mais rápidas devido às otimizações internas de hash (hashing otimizado para lookup). Os ganhos variam conforme o dataset, então sempre meça no seu cenário.
创建成本更高,但由于内部哈希优化(为查找优化的哈希),后续读取速度显著更快。收益因数据集而异,因此请始终在您的场景中进行测量。

3. Evite Closures em Hot Paths
3. 避免在热点路径中使用闭包

Closures podem gerar alocações, especialmente quando capturam variáveis externas. Em código executado frequentemente, isso impacta a performance.
闭包可能会产生内存分配,尤其是在捕获外部变量时。在频繁执行的代码中,这会影响性能。

// Evite: closure captura 'multiplicador'
int multiplicador = 10;
var resultado = lista.Select(x => x * multiplicador).ToList();

// Prefira: use um loop simples para evitar a captura
var resultado = new List<int>(lista.Count);
foreach (var item in lista)
{
    resultado.Add(item * multiplicador);
}

4. Configure o Garbage Collector para seu cenário
4. 根据您的场景配置垃圾回收器

O .NET 10 permite ajuste fino do GC. Para aplicações de alta performance, considere o Server GC com regiões habilitadas.
.NET 10 允许精细调整 GC。对于高性能应用程序,请考虑使用启用区域的 Server GC。

<!-- No .csproj ou runtimeconfig.json -->
<PropertyGroup>
    <ServerGarbageCollection>true</ServerGarbageCollection>
    <GarbageCollectionAdaptationMode>1</GarbageCollectionAdaptationMode>
</PropertyGroup>
// Ou via código para cenários específicos
GCSettings.LatencyMode = GCLatencyMode.SustainedLowLatency;

Para aplicações com picos de alocação conhecidos, GC.TryStartNoGCRegion() pode evitar pausas em momentos críticos.
对于已知有内存分配峰值的应用, GC.TryStartNoGCRegion() 可以避免在关键时刻发生暂停。

5. Use SearchValues para buscas repetitivas em strings
5. 使用 SearchValues 进行字符串中的重复搜索

SearchValues<T> pré-computa estruturas de busca, tornando operações como IndexOfAny muito mais eficientes.
SearchValues<T> 预先计算搜索结构,使 IndexOfAny 等操作更加高效。

// Pré-compute uma vez
private static readonly SearchValues<char> Separadores = 
    SearchValues.Create([' ', ',', ';', '\t', '\n']);

// Use múltiplas vezes
public int ContarPalavras(ReadOnlySpan<char> texto)
{
    int count = 1;
    int index;
    while ((index = texto.IndexOfAny(Separadores)) >= 0)
    {
        count++;
        texto = texto.Slice(index + 1);
    }
    return count;
}

6. Prefira ValueTask para operações que frequentemente completam sincronamente
6. 对于经常同步完成的操作,优先选择 ValueTask

Quando um método async frequentemente retorna de forma síncrona (cache hit, por exemplo), ValueTask evita a alocação de Task.
当异步方法频繁同步返回(例如缓存命中时), ValueTask 可以避免 Task 的分配。

private readonly ConcurrentDictionary<string, Produto> _cache = new();

// ValueTask evita alocação quando há cache hit
public ValueTask<Produto?> ObterProdutoAsync(string id)
{
    if (_cache.TryGetValue(id, out var produto))
    {
        return ValueTask.FromResult<Produto?>(produto);
    }

    return ObterProdutoDoBancoAsync(id);
}

private async ValueTask<Produto?> ObterProdutoDoBancoAsync(string id)
{
    var produto = await _repository.GetByIdAsync(id);
    if (produto is not null)
    {
        _cache.TryAdd(id, produto);
    }
    return produto;
}

ValueTask não deve ser usado indiscriminadamente. Ele não pode ser awaited múltiplas vezes e pode causar boxing se convertido para Task. Use apenas quando a maioria das chamadas (>90%) completa de forma síncrona.
ValueTask 不应随意使用。它不能被多次 await,并且在转换为 Task 时可能导致装箱。仅在大多数调用(>90%)同步完成时使用。

7. Utilize ArrayPool e MemoryPool para arrays temporários
7. 使用 ArrayPool 和 MemoryPool 来处理临时数组

Reutilizar arrays através de pools reduz drasticamente as alocações em operações de I/O ou processamento de buffers.
通过使用对象池来重用数组可以大幅减少 I/O 操作或缓冲区处理中的内存分配。

public async Task ProcessarArquivoAsync(Stream stream)
{
    byte[] buffer = ArrayPool<byte>.Shared.Rent(8192);
    try
    {
        int bytesRead;
        while ((bytesRead = await stream.ReadAsync(buffer)) > 0)
        {
            ProcessarBloco(buffer.AsSpan(0, bytesRead));
        }
    }
    finally
    {
        // clearArray: true evita vazamento de dados entre usos
        ArrayPool<byte>.Shared.Return(buffer, clearArray: true);
    }
}

Os Arrays retornados pelo pool não são zerados por padrão. Se o buffer contiver dados sensíveis, sempre use clearArray: true no Return para evitar vazamento de informações entre usos.
由对象池返回的数组默认情况下不会被清零。如果缓冲区包含敏感数据,请始终使用 clearArray: true 在 Return 中避免信息在多次使用之间泄露。

Para cenários mais complexos, considere MemoryPool<T> que trabalha com Memory<T> e permite maior flexibilidade.
对于更复杂的场景,可以考虑使用 MemoryPool<T> ,它工作于 Memory<T> 并提供更高的灵活性。

8. Implemente ISpanParsable para tipos customizados
8. 为自定义类型实现 ISpanParsable

O .NET 10 favorece parsing baseado em Span. Implemente ISpanParsable<T> para seus tipos de domínio.
.NET 10 优先采用基于 Span 的解析。为您的领域类型实现 ISpanParsable<T> 。

public readonly record struct Cpf : ISpanParsable<Cpf>
{
    private readonly long _valor;

    public static Cpf Parse(ReadOnlySpan<char> s, IFormatProvider? provider)
    {
        // Remove pontuação sem alocar
        Span<char> digitos = stackalloc char[11];
        int pos = 0;

        foreach (char c in s)
        {
            if (char.IsDigit(c) && pos < 11)
                digitos[pos++] = c;
        }

        if (pos != 11)
            throw new FormatException("CPF deve ter 11 dígitos");

        return new Cpf(long.Parse(digitos));
    }

    public static bool TryParse(ReadOnlySpan<char> s, IFormatProvider? provider, out Cpf result)
    {
        // Implementação similar com tratamento de erro
    }
}

9. Use StringComparison explícito
9. 使用显式的 StringComparison

Comparações de string sem especificar o tipo usam cultura corrente, que é mais lento e pode causar bugs sutis.
未指定类型的字符串比较使用当前文化,这更慢并且可能导致细微的 bug。

// Evite: usa CurrentCulture implicitamente
bool igual = str1.Equals(str2);
bool contem = texto.Contains("busca");

// Prefira: significativamente mais rápido para comparações ordinárias
bool igual = str1.Equals(str2, StringComparison.Ordinal);
bool contem = texto.Contains("busca", StringComparison.OrdinalIgnoreCase);

// Para dicionários
var dict = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase);

10. Configure Connection Pooling adequadamente
10. 合理配置连接池

Conexões de banco de dados são recursos caros. Configure o pool de acordo com sua carga.
数据库连接是昂贵的资源。根据您的负载配置连接池。

// Para SQL Server / PostgreSQL
var connectionString = new NpgsqlConnectionStringBuilder
{
    Host = "localhost",
    Database = "mydb",
    Username = "user",
    Password = "pass",

    // Pool settings
    MinPoolSize = 10,
    MaxPoolSize = 100,
    ConnectionIdleLifetime = 300,
    ConnectionPruningInterval = 10
}.ToString();

// Para Entity Framework Core
services.AddDbContextPool<AppDbContext>(options =>
{
    options.UseNpgsql(connectionString);
}, poolSize: 128);

11. Prefira CompositeFormat para Strings formatadas repetidamente
11. 对于重复格式化的字符串,优先选择 CompositeFormat

CompositeFormat pré-compila o formato, evitando parsing repetido em logs ou mensagens frequentes.
CompositeFormat 预编译格式,避免频繁的日志或消息中的重复解析。

// Pré-compile uma vez
private static readonly CompositeFormat LogFormat = 
    CompositeFormat.Parse("[{0:HH:mm:ss}] {1}: {2}");

// Use múltiplas vezes sem parsing repetido
public void Log(string nivel, string mensagem)
{
    var linha = string.Format(null, LogFormat, DateTime.Now, nivel, mensagem);
    Console.WriteLine(linha);
}

12. Use Source Generators para serialização JSON
12. 使用 Source Generators 进行 JSON 序列化

System.Text.Json com source generators elimina reflection em runtime, melhorando performance.
System.Text.Json 使用源生成器可以在运行时消除反射,从而提高性能。

[JsonSerializable(typeof(Produto))]
[JsonSerializable(typeof(List<Produto>))]
[JsonSourceGenerationOptions(
    PropertyNamingPolicy = JsonKnownNamingPolicy.CamelCase,
    DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull)]
public partial class AppJsonContext : JsonSerializerContext { }

// Uso
var json = JsonSerializer.Serialize(produto, AppJsonContext.Default.Produto);
var produto = JsonSerializer.Deserialize(json, AppJsonContext.Default.Produto);

13. Evite Async em Métodos que não precisam
13. 避免在不需要的地方使用异步

O overhead de async/await inclui a criação da máquina de estados. Se o resultado já está disponível, retorne diretamente.
异步/等待的开销包括状态机的创建。如果结果已经可用,直接返回。

// Evite: async desnecessário
public async Task<int> ObterValorAsync()
{
    return await Task.FromResult(42);
}

// Prefira: retorno direto
public Task<int> ObterValorAsync()
{
    return Task.FromResult(42);
}

// Para validações antes de operações async
public Task<Resultado> ProcessarAsync(Dados dados)
{
    if (dados is null)
        return Task.FromResult(Resultado.Invalido);

    return ProcessarInternoAsync(dados);
}

14. Utilize Parallel.ForEachAsync para I/O concorrente controlado
14. 使用 Parallel.ForEachAsync 进行受控的并发 I/O

Para processamento paralelo de I/O, Parallel.ForEachAsync oferece controle fino sobre concorrência.
对于 I/O 的并行处理, Parallel.ForEachAsync 提供了对竞争的精细控制。

public async Task ProcessarUrlsAsync(IEnumerable<string> urls)
{
    var options = new ParallelOptions
    {
        MaxDegreeOfParallelism = 10 // Limite de requisições simultâneas
    };

    await Parallel.ForEachAsync(urls, options, async (url, ct) =>
    {
        var conteudo = await _httpClient.GetStringAsync(url, ct);
        await ProcessarConteudoAsync(conteudo);
    });
}

15. Configure HttpClient corretamente
15. 正确配置 HttpClient

HttpClient deve ser reutilizado. Use IHttpClientFactory para gerenciamento adequado de conexões.
HttpClient 应该被重用。使用 IHttpClientFactory 来适当地管理连接。

// Configuração
services.AddHttpClient("api", client =>
{
    client.BaseAddress = new Uri("https://api.exemplo.com");
    client.DefaultRequestHeaders.Add("Accept", "application/json");
})
.ConfigurePrimaryHttpMessageHandler(() => new SocketsHttpHandler
{
    PooledConnectionLifetime = TimeSpan.FromMinutes(2),
    PooledConnectionIdleTimeout = TimeSpan.FromMinutes(1),
    MaxConnectionsPerServer = 100,
    EnableMultipleHttp2Connections = true
});

// Uso
public class MeuServico(IHttpClientFactory factory)
{
    private readonly HttpClient _client = factory.CreateClient("api");
}

16. Use stackalloc para Buffers Pequenos
16. 使用 stackalloc 处理小缓冲区

Para buffers pequenos e de vida curta, stackalloc evita completamente o uso do heap.
对于小而生命周期短的缓冲区, stackalloc 完全避免使用堆。

public string FormatarCpf(long cpf)
{
    Span<char> buffer = stackalloc char[14]; // XXX.XXX.XXX-XX

    cpf.TryFormat(buffer.Slice(0, 3), out _);
    buffer[3] = '.';
    // ... resto da formatação

    return new string(buffer);
}

// Com limite de segurança para tamanhos variáveis
public void ProcessarDados(int tamanho)
{
    Span<byte> buffer = tamanho <= 256
        ? stackalloc byte[tamanho]
        : new byte[tamanho];

    // Processar...
}

17. Prefira Struct Records para DTOs pequenos
17. 对于小的数据传输对象,优先选择 Struct Records

Para objetos de transferência pequenos e imutáveis, record struct frequentemente evita alocações no heap.
对于小而不可变的数据传输对象, record struct 经常避免堆分配。

// Alocado na stack, sem pressão no GC
public readonly record struct Coordenada(double Latitude, double Longitude);

public readonly record struct ResultadoPaginado<T>(
    T[] Items,
    int Total,
    int Pagina,
    int TamanhoPagina
);

Evite structs grandes (mais de 16-24 bytes) ou com muitos campos, pois o custo de cópia pode superar o benefício.
避免使用大的结构(超过 16-24 字节)或包含许多字段的结构,因为复制成本可能超过收益。

18. Use Regex Source Generators
18. 使用 Regex 源生成器

Regex compilado via source generator é mais rápido e compatível com Native AOT.
通过源生成器编译的 Regex 更快,并且兼容 Native AOT。

public partial class Validadores
{
    [GeneratedRegex(@"^[\w\.-]+@[\w\.-]+\.\w{2,}$", RegexOptions.IgnoreCase)]
    private static partial Regex EmailRegex();

    [GeneratedRegex(@"^\d{5}-?\d{3}$")]
    private static partial Regex CepRegex();

    public static bool ValidarEmail(string email) => EmailRegex().IsMatch(email);
    public static bool ValidarCep(string cep) => CepRegex().IsMatch(cep);
}

19. Minimize Boxing com Generics Constraints
19. 使用泛型约束最小化装箱

Boxing de value types cria objetos no heap. Use constraints genéricos para evitar.
value types 的装箱会在堆上创建对象。使用泛型约束来避免。

// Evite: boxing implícito
public void Processar(IComparable valor) { }

// Prefira: sem boxing
public void Processar<T>(T valor) where T : IComparable<T> { }

// Para interfaces numéricas (.NET 7+)
public T Somar<T>(T a, T b) where T : INumber<T>
{
    return a + b;
}

20. Configure Output Caching em Minimal APIs
20. 在 Minimal APIs 中配置输出缓存

O .NET 10 traz melhorias significativas no Output Caching para Minimal APIs.
.NET 10 为 Minimal APIs 带来了输出缓存的显著改进。

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddOutputCache(options =>
{
    options.AddBasePolicy(builder => builder.Expire(TimeSpan.FromMinutes(5)));

    options.AddPolicy("PorUsuario", builder => builder
        .SetVaryByHeader("Authorization")
        .Expire(TimeSpan.FromMinutes(1)));
});

var app = builder.Build();
app.UseOutputCache();

app.MapGet("/produtos", async (AppDbContext db) =>
    await db.Produtos.ToListAsync())
    .CacheOutput(x => x.Expire(TimeSpan.FromMinutes(10)));

app.MapGet("/perfil", async (HttpContext ctx, AppDbContext db) =>
    await db.Usuarios.FindAsync(ctx.User.GetId()))
    .CacheOutput("PorUsuario");

21. Use Channels para Produtor-Consumidor
21. 使用 Channels 实现生产者-消费者模式

Channel<T> é mais eficiente que BlockingCollection para cenários async de produtor-consumidor.
Channel<T> 比 BlockingCollection 在异步生产者-消费者场景中更高效。

public class FilaDeProcessamento
{
    private readonly Channel<Trabalho> _channel = Channel.CreateBounded<Trabalho>(
        new BoundedChannelOptions(1000)
        {
            FullMode = BoundedChannelFullMode.Wait,
            SingleReader = true,
            SingleWriter = false
        });

    public async ValueTask EnfileirarAsync(Trabalho trabalho, CancellationToken ct = default)
    {
        await _channel.Writer.WriteAsync(trabalho, ct);
    }

    public async Task ProcessarAsync(CancellationToken ct)
    {
        await foreach (var trabalho in _channel.Reader.ReadAllAsync(ct))
        {
            await ProcessarTrabalhoAsync(trabalho);
        }
    }
}

22. Prefira AsNoTracking para Queries somente leitura
22. 对于只读查询,优先选择 AsNoTracking

O Entity Framework mantém tracking de entidades por padrão, o que consome memória e CPU.
Entity Framework 默认会跟踪实体,这会消耗内存和 CPU。

// Para queries de leitura
var produtos = await _context.Produtos
    .AsNoTracking()
    .Where(p => p.Ativo)
    .ToListAsync();

// Configure globalmente para contextos de leitura
services.AddDbContext<ReadOnlyDbContext>(options =>
{
    options.UseNpgsql(connectionString)
           .UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking);
});

23. Utilize StringBuilder com capacidade inicial
23. 使用具有初始容量的 StringBuilder

Para concatenação de strings em loops, StringBuilder com capacidade pré-definida evita realocações.
在循环中进行字符串连接时,具有预定义容量的 StringBuilder 可以避免重新分配。

public string GerarRelatorio(IReadOnlyList<Venda> vendas)
{
    // Estime a capacidade: ~50 chars por linha
    var sb = new StringBuilder(vendas.Count * 50);

    foreach (var venda in vendas)
    {
        sb.Append(venda.Data.ToString("dd/MM/yyyy"));
        sb.Append(" - ");
        sb.Append(venda.Cliente);
        sb.Append(": R$ ");
        sb.AppendLine(venda.Valor.ToString("N2"));
    }

    return sb.ToString();
}

24. Habilite Dynamic PGO
24. 启用动态 PGO

Profile-Guided Optimization dinâmica permite que o JIT otimize baseado no comportamento real da aplicação.
动态 PGO 允许 JIT 根据应用程序的实际行为进行优化。

<PropertyGroup>
    <TieredPGO>true</TieredPGO>
</PropertyGroup>

Ou via variável de ambiente:
或通过环境变量:

DOTNET_TieredPGO=1
DOTNET_TC_QuickJitForLoops=1
DOTNET_ReadyToRun=0

O Dynamic PGO pode trazer ganhos de 10-30% em aplicações de longa execução após o warm-up.
动态 PGO 在应用程序预热后可以带来 10-30%的性能提升。

25. Meça ANTES DE OTIMIZAR
25. 在优化之前进行测量

A dica mais importante: use ferramentas de profiling para identificar gargalos reais.
最重要的建议:使用性能分析工具来识别真正的瓶颈。

// BenchmarkDotNet para microbenchmarks
[MemoryDiagnoser]
[SimpleJob(RuntimeMoniker.Net100)]
public class MeusBenchmarks
{
    [Benchmark(Baseline = true)]
    public void AbordagemOriginal() { }

    [Benchmark]
    public void AbordagemOtimizada() { }
}

Ferramentas essenciais para profiling:
性能分析的关键工具:

  • dotnet-counters: Métricas em tempo real de GC, threadpool, exceções
    dotnet-counters:GC、线程池和异常的实时指标
  • dotnet-trace: Coleta traces para análise detalhada
    dotnet-trace: 收集跟踪信息以进行详细分析
  • dotnet-dump: Análise de memória e diagnóstico de leaks
    dotnet-dump: 内存分析和泄漏诊断
  • PerfView: Análise profunda de CPU e alocações
    PerfView: 深入分析 CPU 和内存分配
  • Visual Studio Profiler: Integração completa com debugging
    Visual Studio Profiler: 与调试功能完全集成
# Monitorar métricas básicas
dotnet-counters monitor --process-id <PID> --counters System.Runtime

# Coletar trace de 30 segundos
dotnet-trace collect --process-id <PID> --duration 00:00:30

Conclusão   结论

Performance em .NET 10 é resultado de escolhas conscientes em cada camada da aplicação. Desde a escolha de estruturas de dados apropriadas até a configuração adequada de infraestrutura, cada decisão impacta o resultado final.
.NET 10 的性能是应用程序每一层做出的自觉选择的结果。从选择合适的数据结构到正确配置基础设施,每一个决策都会影响最终结果。

Lembre-se: otimização prematura é a raiz de todo mal. Meça primeiro, identifique os gargalos reais, e então aplique as técnicas apropriadas. As dicas apresentadas aqui são ferramentas no seu arsenal, ou como eu costumo chamar... seu cinto de utilidades, use-as quando os dados indicarem necessidade.
记住:过早优化是万恶之源。先测量,识别真正的瓶颈,然后应用适当的技术。这里提出的建议是您工具箱中的工具,或者像我喜欢说的...您的实用工具腰带,在数据表明需要时使用它们。