Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 删除字符串中第一个字符的最快方法_C#_String_Substring_Performance_Trim - Fatal编程技术网

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

C# 删除字符串中第一个字符的最快方法,c#,string,substring,performance,trim,C#,String,Substring,Performance,Trim,假设我们有以下字符串 string data= "/temp string"; 如果我们想删除第一个字符/,我们可以通过以下多种方式进行: data.Remove(0,1); data.TrimStart('/'); data.Substring(1); 但是,我真的不知道哪一个算法最好,而且速度更快 有最好的还是都一样的吗?如果你真的在乎的话,你可以分析一下。写一个多次迭代的循环,看看会发生什么。然而,这并不是应用程序中的瓶颈,而且TrimStart在语义上似乎是最正确的。在优化之前,努力

假设我们有以下字符串

string data= "/temp string";
如果我们想删除第一个字符
/
,我们可以通过以下多种方式进行:

data.Remove(0,1);
data.TrimStart('/');
data.Substring(1);
但是,我真的不知道哪一个算法最好,而且速度更快

有最好的还是都一样的吗?

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

我猜
Remove
Substring
会并列第一,因为它们都会发出固定大小的字符串,而
TrimStart
会从左侧扫描每个字符,并对每个字符进行测试,然后必须执行与其他两种方法完全相同的工作。不过,说真的,这是在吹毛求疵。

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

第一个选项比第三个选项需要更多的工作才能理解-我认为
子字符串
选项是最常见和可读的

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


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

我知道这是超优化的领域,但这似乎是启动
BenchmarkDotNet
的好借口。此测试的结果(甚至在.NET Core上)是
子字符串
删除
稍微快一点,在这个示例测试中:
删除
的速度为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>();
        }
    }
}

是否仍要删除第一个字符,还是需要检查此字符是否确实是
/
TrimStart
不会删除第一个字符,它将从开头删除
n
字符<代码>子字符串是最快的。我只需要删除任何第一个字符。如果要删除任何第一个字符,
TrimStart()
是完全不可能的。@BoltClock:是的,这就是我说的(键入)。
TrimStart
是最不正确的,因为
“//temp string.TrimStart('/'))
将不只是删除第一个
“/”
。该函数的名称很糟糕。“我不是一个C#guy。@StefanKendall:看看Tag实际上,
Substring
Remove
快,因为
Remove
调用
Substring
。@Jaroslav:这不是真的。
Substring
Remove
都依赖于一个私有方法,
FillSubstring
。没有验证它,但听起来很有道理:
string Remove(这个字符串源,int-from,int-to){return source.Substring(0,from)+source.Substring(to);}
@Jaroslav:我正在关注mscorlib.dll中两个方法在相当传统的Windows开发环境中的反射器反汇编。它们都调用
System.PInvoke.EE.AllocateString
来分配目标字符串对象,然后调用
FillSubstring
来复制整个字符串。“我看错东西了吗?”马塞洛:不管怎样,你的第一句话最初说的是一件完全不同的事情。我可能应该使用更好的措辞,但这一点是正确的(
Substring
Remove
)。我不打算作进一步的评论,因为讨论占用了我足够的时间。我现在通过调用每一个来检查大约90000000,结果如下:Remove:06.63-TrimStart:04.71-subString:03.09所以from result subString是最好的。请记住,当您以这种方式测试性能时,您会受到CPU缓存的影响,因此,您需要对预先填充数组(列表)的随机字符串执行此操作,并随机选择该数组(列表)的元素。
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 |