C# - Usando o método Reverse e comparando o desempenho


Nesta dica de C# veremos como inverter uma string usando o método Reverse comparando seu desempenho.

Para inverter uma string você pode usar diversos métodos, onde alguns são mais rápidos que outros, uns usam mais linhas de código que outros.

A partir da versão 3.5 da plataforma .NET você pode usar uma série de métodos de extensão que fazem parte do namespace System.Linq para atuar sobre qualquer tipo que implemente IEnumerable<T>.

Isso inclui o tipo string em C# (System.String), que implementa IEnumerable<char>. Um dos métodos de extensão mais úteis que vem com Linq é o método Reverse : Enumerable.Reverse<TSource>.

Como este é um método de extensão, você pode usá-lo em uma instância de uma string como se fosse um método de instância.

Usando o VS 2017 Community crie um projeto do tipo Console Application inclua o código abaixo no método Main() da classe Program:

 using System.Linq;
using static System.Console;
namespace CShp_StringReverse
{
    class Program
    {
        static void Main(string[] args)
        {
            string texto = "Macoratti .net - Quase tudo para .NET";
            WriteLine($"Texto Normal   : {texto}");
            string textoInvertido = new string(texto.Reverse().ToArray());
            WriteLine($"Texto Invertido: {textoInvertido}");
            ReadLine();
        }
    }
}
             

Como o método Reverse retorna um objeto do tipo ReverseIteratos<char> precisamos converter de volta para um array e usar o array para instanciar uma  nova string.

Abaixo vemos o resultado deste código :

Aqui usamos apenas uma linha de código e o método ToArray().

Vamos agora criar um método estático chamado InverteString() na classe Program:

using System;
using System.Linq;
using static System.Console;
namespace CShp_StringReverse
{
    class Program
    {
        public static string InverteString(string s)
        {
            char[] arr = s.ToCharArray();
            Array.Reverse(arr);
            return new string(arr);
        }
        static void Main(string[] args)
        {
            string texto = "Macoratti .net - Quase tudo para .NET";
            WriteLine($"Texto Normal   : {texto}");
            string textoInvertido = new string(texto.Reverse().ToArray());
            WriteLine($"Texto Invertido: {textoInvertido}");
            WriteLine(InverteString("Usando o método InverteString"));
            ReadLine();            
        }
    }
}

O método estático InverteString(string s) recebe uma string como parâmetro.

Ele copia a string para um array usando ToCharArray() que retorna o buffer mutável char[] da string.

A seguir o método usa Array.Reverse() para modificar a ordem dos caracteres.

Veja o resultado obtido:

Vamos agora comparar os dois métodos e verificar qual é mais rápido para uma quantidade grande de inversões.

Inclua o código abaixo no método Main():

using System;
using System.Diagnostics;
using System.Linq;
using static System.Console;
namespace CShp_StringReverse
{
    class Program
    {
        public static string InverteString(string s)
        {
            char[] arr = s.ToCharArray();
            Array.Reverse(arr);
            return new string(arr);
        }
        static void Main(string[] args)
        {
            int soma = 0;
            const int maximo = 10000000;
            // Versão 1:  inverter usando ToCharArray.
            var s1 = Stopwatch.StartNew();
            for (int i = 0; i < maximo; i++)
            {
                soma += InverteString("Macoratti .net - Quase tudo para .NET").Length;
            }
            s1.Stop();
            // Versão 2: inverte usando Reverse direto com ToArray
            var s2 = Stopwatch.StartNew();
            string texto = "Macoratti .net - Quase tudo para .NET";
            for (int i = 0; i < maximo; i++)
            {
                soma += new string(texto.Reverse().ToArray()).Length;
            }
            s2.Stop();
            WriteLine($"Versão 1 : InverteString() : {s1.Elapsed.TotalMilliseconds}");
            WriteLine($"Versão 2 : Direto com ToArray() : {s2.Elapsed.TotalMilliseconds}");
            ReadLine();
        }
    }
}

Executando o projeto teremos o seguinte resultado :

Concluímos que o método usando InverteString() é dez vezes mais rápido.

Pegue o projeto completo aqui :  CShp_StringReverse.zip

"E disse-lhes: Ide por todo omundo, pregai o evangelho a toda criatura. Quem crer e for batizado será salvo; mas quem não crer será condenado."
Marcos 16:15,16

Referências:


José Carlos Macoratti