我有以下基于代码的on this question. 在这里拉小提琴.https://dotnetfiddle.net/vchYHj

using System;
using System.Diagnostics;
public class Program
{
    public static void Main()
    {
        ReadOnlySpan<byte> r = stackalloc byte[] { 52, 48, 48, 55, 48 };
        var sw = new Stopwatch();
        int result = 0;


        sw.Restart();
        for (int i=0; i<10000000; i++) result =  Test1(r);
        sw.Stop();
        Console.WriteLine($"Test1 took {sw.ElapsedMilliseconds}ms {result}");


        sw.Restart();
        for (int i=0; i<10000000; i++) result = Test2(r);
        sw.Stop();
        Console.WriteLine($"Test2 took {sw.ElapsedMilliseconds}ms {result}");

    }

    public static int Test1(ReadOnlySpan<byte> source)
    {
        int answer = 0;
        int index = 0;
        int c = source[index];
        answer = c - '0';
        while (true)
        {
            index++;
            if ((uint)index >= (uint)source.Length)
                break;
            c = source[index];
            answer = answer * 10 + c - '0';
        }
         return answer;
    }
    
    public static int Test2(ReadOnlySpan<byte> data)
    {
        if (System.Buffers.Text.Utf8Parser.TryParse(data, out int value, out int bytes))
        {
            return(value);
        }   
        else
            return(0);
    }
}

Test1 took 244ms 40070
Test2 took 99ms 40070

为什么第二种方法Test1在.NET小提琴上要慢得多,因为它完全是从.NET开源复制而来的,而且更简单?

https://github.com/dotnet/runtime/blob/main/src/libraries/System.Private.CoreLib/src/System/Buffers/Text/Utf8Parser/Utf8Parser.Integer.Unsigned.N.cs#L53

推荐答案

为什么第二个方法Test1在.NET小提琴上要慢得多,

其中一个原因是,由.NET Fiddle代码编译的代码没有得到优化.作为一个简单的示例,请考虑以下代码

#if DEBUG
    Console.WriteLine("DEBUG");
#else
    Console.WriteLine("RELEASE");
#endif

当使用.NET小提琴执行时,将打印DEBUG.

如果你想做基准测试,我建议先阅读Eric Lippert关于这个主题的blog series篇文章.对调试版本而不是发布版本进行基准测试只是其中列出的常见错误之一.

Csharp相关问答推荐

有没有一种方法可以将模拟实现委托给实际的类,而不必设置每个方法?

Blazor:计算值或保留为默认值

C#将参数传递给具有变化引用的变量

当打印一行x个项目时,如何打印最后一行项目?

为什么在ANTLR4中会出现不匹配的输入错误?""

为什么将鼠标悬停在DateTimeOffset上只显示Hour值?

如何在C#中使用正则表达式抓取用逗号分隔的两个单词?

如何将不同类型的扩展参数的javascript函数转换成C#风格?

使用两个不同的枚举作为Switch语句中的CASE生成唯一值

JSON空引用异常仅在调试器中忽略try-Catch块,但在其他上下文中捕获得很好

从.Net 6 DLL注册和检索COM对象(Typelib导出:类型库未注册.(异常来自HRESULT:0x80131165))

使用泛型可空类实现接口

如何在不复制或使用输出的情况下定义项目依赖

在Windows Plesk上发布ASP.NET Core 7 Web API-错误:无法加载文件或程序集';Microsoft.Data.SqlClient';

Azure函数-在外部启动类中生成配置时出错

System.NotSupportdException:流不支持读取

解决方案:延长ABP框架和ANGING OpenIddict中的令牌生命周期

用于ASP.NET核心的最小扩展坞

C#中使用ReadOnlySpan的泛型类型推理

如何使ExecuteAsync异步运行