假设我们有以下字符串
string data= "/temp string";
如果我们要删除第一个字符/
,我们可以通过很多方式来完成,例如:
data.Remove(0,1);
data.TrimStart('/');
data.Substring(1);
但是,我真的不知道哪一个拥有最好的算法并且做得更快.. 有一个是最好的还是全部都是一样的?
第二个选项实际上与其他选项不同 - 如果字符串是“/// foo”,它将变为“foo”而不是“// foo”。
第一个选项比第三个选项需要更多的工作来理解 - 我会将Substring
选项视为最常见和可读的选项。
(显然,每个作为单独的语句都不会做任何有用的事情 - 你需要将结果分配给变量,可能是data
本身。)
我不会在这里考虑性能,除非它实际上成为你的问题 - 在这种情况下,你知道的唯一方法是拥有测试用例,然后很容易为每个选项运行这些测试用例比较结果。我希望Substring
可能是最快的,因为Substring
总是最终从原始输入的一个块创建一个字符串,而Remove
必须至少可能将起始块和结束块粘合在一起。
我猜想Remove
和Substring
会排在第一位,因为它们都会在字符串中固定大小的部分,而TrimStart
从左边进行扫描并对每个字符进行测试然后必须执行完全相同的操作作为另外两种方法工作。但说真的,这是分裂的头发。
如果你真的关心的话,你可以描述它。编写一个循环的多次迭代,看看会发生什么。但是,这可能不是您应用程序中的瓶颈,TrimStart似乎在语义上最正确。努力在优化之前可读地编写代码。
我知道这是超优化的土地,但它似乎是踢BenchmarkDotNet
车轮的一个很好的借口。这个测试的结果(在.NET Core上甚至)是Substring
比Remove
稍微快一点,在这个样本测试中:19.37ns对Remove
的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 |