代码之家  ›  专栏  ›  技术社区  ›  Amr Badawy

删除字符串中第一个字符的最快方法

  •  170
  • Amr Badawy  · 技术社区  · 15 年前

    假设我们有以下字符串

    string data= "/temp string";
    

    如果我们要删除第一个字符 /

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

    但是,我真的不知道哪一个有最好的算法而且做得更快。。
    有一个是最好的还是所有的都一样?

    4 回复  |  直到 7 年前
        1
  •  159
  •   Jon Skeet    15 年前

    第二个选项实际上与其他选项不同—如果字符串是“//foo”,它将变成“foo”,而不是“//foo”。

    第一个选项比第三个选项需要更多的工作来理解-我将查看 Substring 选项作为最常见和可读的。

    (显然,作为一个单独的语句,它们中的每一个都没有任何用处—您可能需要将结果赋给一个变量 data 本身。)

    在这里,我不会考虑性能,除非它实际上对您来说是一个问题—在这种情况下,您知道的唯一方法就是拥有测试用例,然后很容易为每个选项运行这些测试用例并比较结果。我希望 子串 可能是这里最快的,因为 子串 最后总是从原始输入的单个块创建一个字符串,而 Remove 必须至少 可能 将起始块和结束块粘在一起。

        2
  •  18
  •   Nicholas Petersen    6 年前

    我知道这是一片超优化的土地,但这似乎是一个很好的借口来踢车轮 BenchmarkDotNet Substring 比…快一点 Remove ,在这个样本测试中:19.37ns对22.52ns 删除 . 所以大约快了16%。

    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>();
            }
        }
    }
    

    结果:

    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 |
    
        3
  •  9
  •   Marcelo Cantos    15 年前

    我猜是的 Remove Substring 因为它们都能咬住固定大小的绳子,而 TrimStart 从左边扫描每个字符,然后执行与其他两种方法完全相同的工作。不过,说真的,这真是令人毛骨悚然。

        4
  •  6
  •   Stefan Kendall    15 年前

    如果你真的在乎的话,你可以把它描绘出来。写一个包含许多迭代的循环,看看会发生什么。然而,这并不是应用程序中的瓶颈,TrimStart在语义上似乎是最正确的。在优化之前,尽量写可读的代码。