83 votes

String.Replace () et StringBuilder.Replace ()

J'ai une chaîne dont j'ai besoin pour remplacer les marqueurs avec des valeurs à partir d'un dictionnaire. Il doit être aussi efficace que possible. Faire une boucle avec une chaîne.remplacer juste à consommer de la mémoire (les chaînes sont immuables, rappelez-vous). Serait StringBuilder.Replace() sera mieux car c'est a été conçu pour fonctionner avec les manipulations de chaînes?

J'espérais éviter les frais de RegEx, mais si c'est pour être plus efficaces, alors ainsi soit-il.

Note: je ne m'inquiète pas à propos de la complexité du code, seulement la façon rapide, il s'exécute et la mémoire qu'il consomme.

Moyen stats: 255-1024 caractères, de 15 à 30 touches dans le dictionnaire.

80voto

DustinDavis Points 7808

À l'aide de RedGate Profiler à l'aide du code suivant

class Program
    {
        static string data = "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz";
        static Dictionary<string, string> values;

        static void Main(string[] args)
        {
            Console.WriteLine("Data length: " + data.Length);
            values = new Dictionary<string, string>()
            {
                { "ab", "aa" },
                { "jk", "jj" },
                { "lm", "ll" },
                { "yz", "zz" },
                { "ef", "ff" },
                { "st", "uu" },
                { "op", "pp" },
                { "x", "y" }
            };

            StringReplace(data);
            StringBuilderReplace1(data);
            StringBuilderReplace2(new StringBuilder(data, data.Length * 2));

            Console.ReadKey();
        }

        private static void StringReplace(string data)
        {
            foreach(string k in values.Keys)
            {
                data = data.Replace(k, values[k]);
            }
        }

        private static void StringBuilderReplace1(string data)
        {
            StringBuilder sb = new StringBuilder(data, data.Length * 2);
            foreach (string k in values.Keys)
            {
                sb.Replace(k, values[k]);
            }
        }

        private static void StringBuilderReplace2(StringBuilder data)
        {
            foreach (string k in values.Keys)
            {
                data.Replace(k, values[k]);
            }
        }
    }
  • Chaîne de caractères.Remplacer = 5.843 ms
  • StringBuilder.Remplacez #1 = 4.059 ms
  • Stringbuilder.Remplacez #2 = 0.461 ms

Longueur de chaîne = 1456

stringbuilder #1 crée le stringbuilder dans la méthode alors que #2 n'est pas tellement la différence de performance sera à la fin de la même plus probable puisque vous êtes juste déplacer que le travail de la méthode. Si vous commencez avec un stringbuilder au lieu d'une chaîne puis #2 pourrait être le chemin à parcourir à la place.

Aussi loin que la mémoire, à l'aide de RedGateMemory profiler, il n'y a rien à s'inquiéter jusqu'à ce que vous obtenir dans BEAUCOUP de remplacer les opérations de stringbuilder va gagner ensemble.

10voto

RMD Points 1629

Cela peut être de l'aide:

http://blogs.msdn.com/b/debuggingtoolbox/archive/2008/04/02/comparing-regex-replace-string-replace-and-stringbuilder-replace-which-has-better-performance.aspx

La réponse semble être que Chaîne de caractères.Remplacer est plus rapide, mais il peut avoir un plus grand impact sur votre empreinte mémoire / la collecte des ordures frais généraux.

7voto

Andrei Points 25595

Oui, StringBuilder vous donnera à la fois gain de vitesse et de mémoire (essentiellement parce qu'il ne créera pas d'instance de chaîne à chaque fois que vous ferez une manipulation avec elle - StringBuilder fonctionne toujours avec le même objet). Voici un lien MSDN avec quelques détails.

6voto

Henk Holterman Points 153608

Stringbuilder.replace serait-il meilleur [que String.Replace]

Oui, beaucoup mieux. Et si vous pouvez estimer une limite supérieure pour la nouvelle chaîne (il semble que vous puissiez le faire), cela sera probablement assez rapide.

Quand vous le créez comme:

   var sb = new StringBuilder(inputString, pessimisticEstimate);
 

alors le StringBuilder n'aura pas à réallouer son tampon.

1voto

supercat Points 25534

La conversion des données d'une chaîne en un constructeur de chaînes prend du temps. Si vous n'effectuez qu'une seule opération de remplacement, il est possible que cette heure ne soit pas récupérée par les améliorations d'efficacité inhérentes à StringBuilder. D'un autre côté, si l'on convertit une chaîne en StringBuilder, puis effectue plusieurs opérations de remplacement dessus et la reconvertit à la fin, l'approche StringBuilder est susceptible d'être plus rapide.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X