web-dev-qa-db-fra.com

Moyen le plus rapide de supprimer le premier caractère d'une chaîne

Disons que nous avons la chaîne suivante

string data= "/temp string";

Si nous voulons supprimer le premier caractère /, nous pouvons le faire de différentes manières, par exemple:

data.Remove(0,1);
data.TrimStart('/');
data.Substring(1);

Mais, vraiment, je ne sais pas lequel a le meilleur algorithme et le faire plus rapidement ..
Y at-il un qui est le meilleur ou tous sont les mêmes?

180
Amr Badawy

La deuxième option n'est vraiment pas la même que les autres - si la chaîne est "/// foo", elle deviendra "foo" au lieu de "// foo".

La première option nécessite un peu plus de travail à comprendre que la troisième - je considérerais l'option Substring comme la plus courante et lisible.

(Il est évident que chacune d'elles en tant qu'instruction individuelle ne fera rien d'utile - vous devrez assigner le résultat à une variable, éventuellement data elle-même.)

Je ne tiendrais pas compte des performances ici à moins que cela ne devienne réellement un problème pour vous. Dans ce cas, la seule façon de le savoir serait d’avoir des scénarios de test, puis il est facile d’exécuter ces scénarios de test pour chaque option. comparer les résultats. Je pense que Substring sera probablement le plus rapide ici, tout simplement parce que Substring finit toujours par créer une chaîne à partir d'un seul morceau de l'entrée d'origine, alors que Remove doit au moins - potentiellement coller ensemble un morceau de départ et un morceau de fin.

130
Jon Skeet

Je suppose que Remove et Substring seraient à égalité pour la première place, puisqu'ils slurpaient tous les deux une portion de taille fixe de la chaîne, alors que TrimStart effectuait un balayage de gauche avec un test sur chaque caractère et doit ensuite effectuer exactement le même travail que les deux autres méthodes. Sérieusement, c'est couper les cheveux en quatre.

8
Marcelo Cantos

Vous pouvez le profiler, si cela vous intéresse vraiment. Ecrivez une boucle de nombreuses itérations et voyez ce qui se passe. Il y a toutefois des chances pour que ce ne soit pas le goulot d'étranglement de votre application, et TrimStart semble le plus sémantiquement correct. S'efforcer d'écrire du code en lecture avant l'optimisation.

6
Stefan Kendall

Je sais que c’est une terre d’optimisation, mais c’était une bonne excuse pour lancer BenchmarkDotNet. Le résultat de ce test (sur .NET Core even) est que Substring est légèrement plus rapide que Remove, dans cet exemple de test: 19.37ns vs 22.52ns pour Remove. Donc, certains ~ 16% plus vite.

using System;
using BenchmarkDotNet.Attributes;

namespace BenchmarkFun
{
    public class StringSubstringVsRemove
    {
        public readonly string SampleString = " My name is Daffy Duck.";

        [Benchmark]
        public string StringSubstring() => SampleString.Substring(1);

        [Benchmark]
        public string StringRemove() => SampleString.Remove(0, 1);

        public void AssertTestIsValid()
        {
            string subsRes = StringSubstring();
            string remvRes = StringRemove();

            if (subsRes == null
                || subsRes.Length != SampleString.Length - 1
                || subsRes != remvRes) {
                throw new Exception("INVALID TEST!");
            }
        }
    }

    class Program
    {
        static void Main()
        {
            // let's make sure test results are really equal / valid
            new StringSubstringVsRemove().AssertTestIsValid();

            var summary = BenchmarkRunner.Run<StringSubstringVsRemove>();
        }
    }
}

Résultats:

BenchmarkDotNet=v0.11.4, OS=Windows 10.0.17763.253 (1809/October2018Update/Redstone5)
Intel Core i7-6700HQ CPU 2.60GHz (Skylake), 1 CPU, 8 logical and 4 physical cores
.NET Core SDK=3.0.100-preview-010184
  [Host]     : .NET Core 3.0.0-preview-27324-5 (CoreCLR 4.6.27322.0, CoreFX 4.7.19.7311), 64bit RyuJIT
  DefaultJob : .NET Core 3.0.0-preview-27324-5 (CoreCLR 4.6.27322.0, CoreFX 4.7.19.7311), 64bit RyuJIT

|          Method |     Mean |     Error |    StdDev |
|---------------- |---------:|----------:|----------:|
| StringSubstring | 19.37 ns | 0.3940 ns | 0.3493 ns |
|    StringRemove | 22.52 ns | 0.4062 ns | 0.3601 ns |
5
Nicholas Petersen