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

假设我们有以下字符串

string data= "/temp string";

如果我们想要删除第一个字符/,我们可以通过很多方法来做,例如:

data.Remove(0,1);
data.TrimStart('/');
data.Substring(1);
但是,我真的不知道哪一个有最好的算法,做得更快。< br / > 有一个是最好的还是所有都一样?

389084 次浏览

如果你真的在乎,你可以侧写。编写一个多次迭代的循环,看看会发生什么。然而,这可能不是应用程序中的瓶颈,TrimStart似乎在语义上是最正确的。在优化之前,努力编写可读性强的代码。

我猜RemoveSubstring将并列第一,因为它们都吸收了固定大小的字符串部分,而TrimStart从左侧扫描,对每个字符进行测试,然后必须执行与其他两个方法完全相同的工作。但说真的,这是吹毛求疵。

第二个选项与其他选项不一样——如果字符串是"///foo",它将变成"foo"而不是"//foo"。

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

(显然,作为单独的语句,它们中的每一个都不会做任何有用的事情——你需要将结果分配给一个变量,可能是data本身。)

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

我知道这是一个超级优化的领域,但这似乎是一个很好的借口来踢BenchmarkDotNet的轮子。这个测试的结果(甚至在。net Core上)是SubstringRemove稍微快一点,在这个示例测试中:Remove为19.37ns vs 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 |

net核心中也是如此:

data = data[1..];