Compartilhar via


Usar o Visual C# para melhorar o desempenho da concatenação de cadeia de caracteres

Este artigo fornece informações sobre como melhorar o desempenho da concatenação de cadeia de caracteres no Visual C#.

Versão original do produto: Visual C#
Número original do KB: 306822

Resumo

Este artigo mostra os benefícios de usar a StringBuilder classe em relação às técnicas tradicionais de concatenação. As cadeias de caracteres no Microsoft .NET Framework são invariáveis (ou seja, o texto referenciado é somente leitura após a alocação inicial). Ele fornece muitos benefícios de desempenho e apresenta alguns desafios para o desenvolvedor que está acostumado com técnicas de manipulação de cadeia de caracteres C/C++.

Este artigo refere-se ao namespace System.Textda Biblioteca de Classes do .NET Framework.

Descrição de cadeias de caracteres no .NET Framework

Uma técnica para melhorar a concatenação strcat() de cadeia de caracteres no Visual C/C++ é alocar uma matriz de caracteres grande como um buffer e copiar dados de cadeia de caracteres para o buffer. No .NET Framework, uma cadeia de caracteres é imutável, não pode ser modificada no local. O operador de concatenação C# + cria uma nova cadeia de caracteres e causa desempenho reduzido quando concatena grandes quantidades de texto.

No entanto, o .NET Framework inclui uma StringBuilder classe otimizada para concatenação de cadeia de caracteres. Ele fornece os mesmos benefícios que usar uma matriz de caracteres em C/C++ e aumentar automaticamente o tamanho do buffer (se necessário) e rastrear o comprimento para você. O aplicativo de exemplo neste artigo demonstra o uso da classe e compara o desempenho com a StringBuilder concatenação.

Compilar e executar um aplicativo de demonstração

  1. Inicie o Visual Studio e crie um novo aplicativo de console do Visual C#.

  2. O código a seguir usa os operadores de += concatenação e a StringBuilder classe para cronometrar 5.000 concatenações de 30 caracteres cada. Adicione esse código ao procedimento principal.

    const int sLen = 30, Loops = 5000;
    int i;
    string sSource = new String('X', sLen);
    string sDest = "";
    
    // Time string concatenation.
    var stopwatch = System.Diagnostics.Stopwatch.StartNew();
    for (i = 0; i < Loops; i++) sDest += sSource;
    stopwatch.Stop();
    Console.WriteLine($"Concatenation took {stopwatch.ElapsedMilliseconds} ms.");
    
    // Time StringBuilder.
    stopwatch.Restart();
    System.Text.StringBuilder sb = new System.Text.StringBuilder((int)(sLen * Loops * 1.1));
    for (i = 0; i < Loops; i++) 
        sb.Append(sSource);
    sDest = sb.ToString();
    stopwatch.Stop();
    Console.WriteLine($"String Builder took {stopwatch.ElapsedMilliseconds} ms.");
    
    // Make the console window stay open
    // so that you can see the results when running from the IDE.
    Console.WriteLine();
    Console.Write("Press Enter to finish ... ");
    Console.Read();
    
  3. Salve o aplicativo. Pressione F5 para compilar e executar o aplicativo. As janelas do console devem exibir uma saída semelhante aos exemplos:

    Concatenation took 348 ms.
    String Builder took 0 ms.
    Press ENTER to finish...
    
  4. Pressione ENTER para interromper a execução do aplicativo e fechar a janela do console.

Solução de problemas

  • Se você estiver em um ambiente que dá suporte ao streaming de dados, como em um formulário Web ASPX ou se seu aplicativo estiver gravando os dados em disco, considere evitar a sobrecarga de buffer de concatenação ou o StringBuilder, e grave os dados diretamente no fluxo por meio do Response.Write método ou do método apropriado para o fluxo em questão.

  • Tente reutilizar o existente StringBuilder class em vez de realocar sempre que precisar de um. O que limita o crescimento do heap e reduz a coleta de lixo. Em ambos os casos, o uso da StringBuilder classe faz uso mais eficiente do heap do que o uso do + operador.

Referências

A StringBuilder classe contém muitos outros métodos para manipulação de cadeia de caracteres in-loco que não são descritos neste artigo. Para obter mais informações, pesquise StringBuilder na Ajuda on-line.