Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/279.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# 自托管Owin比asp.Net核心Api(AspNetCore 1.1.1)更快(.Net Framework 4.5)_C#_.net_Asp.net Core_Owin_.net Core - Fatal编程技术网

C# 自托管Owin比asp.Net核心Api(AspNetCore 1.1.1)更快(.Net Framework 4.5)

C# 自托管Owin比asp.Net核心Api(AspNetCore 1.1.1)更快(.Net Framework 4.5),c#,.net,asp.net-core,owin,.net-core,C#,.net,Asp.net Core,Owin,.net Core,我正在对使用Owin和.NET4.5框架的自托管Web Api与使用ASPNETCore1.1.1和.NETCore的自托管Web Api进行性能比较。令我惊讶的是,我发现自托管Web Api比aspnet核心更快。测试性能的服务器端或客户端代码有什么问题吗 对于Web上的大多数基准测试,据说AspNetCore通常比Web Api快。但是这次测试给了我不同的结果。请看下面的结果 带Owin的自托管Web Api-耗时-已用毫秒=10319.8858 带Kestrel的AspNet核心Web A

我正在对使用Owin和.NET4.5框架的自托管Web Api与使用ASPNETCore1.1.1和.NETCore的自托管Web Api进行性能比较。令我惊讶的是,我发现自托管Web Api比aspnet核心更快。测试性能的服务器端或客户端代码有什么问题吗

对于Web上的大多数基准测试,据说AspNetCore通常比Web Api快。但是这次测试给了我不同的结果。请看下面的结果

带Owin的自托管Web Api-耗时-已用毫秒=10319.8858

带Kestrel的AspNet核心Web Api-所用时间-已用毫秒=11903.8001

使用Owin和.Net framework 4.5的自托管Web Api的服务器端代码

    public IEnumerable<string> Get()
    {
        System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
        sw.Start();
        StringBuilder bigString = new StringBuilder();
        for (long i = 0; i < 6000000; i++)
        {
            bigString.Append("This really big string" + Environment.NewLine);
        }
        var someString = "Elapsed time" + sw.Elapsed.TotalMilliseconds + "data " + bigString.ToString();
        return new string[] { someString };
    }
aspnet core web api aspnet core 1.1.1与.Net core的服务端代码

 public IEnumerable<string> Get()
    {
        System.Diagnostics.Stopwatch sw=new System.Diagnostics.Stopwatch();
        sw.Start();
        StringBuilder bigString = new StringBuilder();            
        for (long i = 0; i < 6000000; i++)
        {
            bigString.Append("This really big string" + Environment.NewLine);
        }
        var someString= "Elapsed time" + sw.Elapsed.TotalMilliseconds + "data " + bigString.ToString();
        return new string[] { someString };
    }
用于测试性能的客户端逻辑

string baseAddress = "http://localhost:5000/";
        System.Diagnostics.Stopwatch watch = new System.Diagnostics.Stopwatch();
        // Start OWIN host 
        //using (WebApp.Start<Startup>(url: baseAddress))
        {
            // Create HttpCient and make a request to api/values 
            HttpClient client = new HttpClient();                            
            watch.Start();
            var response = client.GetAsync(baseAddress + "api/values").Result;
            //Console.WriteLine(response);
           var d= response.Content.ReadAsStringAsync().Result;
            //Console.WriteLine();
            watch.Stop();
        }
        Console.WriteLine(Environment.NewLine + "Elapsed miliseconds= " + watch.Elapsed.TotalMilliseconds);
        Console.ReadLine();

所讨论的测试完全没有意义

第一个错误假设:创建/提交大数据等于性能测试 你正在测试你的记忆力有多快

当您迭代6000000次向缓冲区添加字符串时,您可以有效地测试分配和垃圾收集的速度,因为每次字符串生成器的缓冲区满了,它都需要扩展,并将旧内容复制到新的字符串生成器

一旦给定的垃圾收集生成已满,就需要对其进行收集

除此之外,您还可以调用bigString.ToString,它基本上读取整个缓冲区并再次将其分配到自己的内存中

您的字符串是24字节长的22+新行。您进行了600000 600万次迭代。这是一个6000000*24*2的缓冲区大小。NET中的字符串在内部为UTF-16=2880000字节或274.658 MB。StringBuilder初始化为16个字符32个字节,请参阅

这意味着,为了增加到2880000字节,StringBuilder需要将自身大小调整为公式16*2^n-1的26倍;对于n=26,这将产生16*2^25,这将产生536870912字节512 MB的缓冲区

但是在调整大小的过程中,您总共分配了1073741808字节,大约1GB的RAM,GC很可能会分配其中的大部分。再加上调用bigString.ToString时的2880000字节。因此,您分配了大约1.75 GB的RAM

要想在图片中看到这一点,让WolframAlpha为您绘制:*2^n-1,+n%3D1+到+26]

总之,您测量了内存分配1.75 GB的速度,StringBuilder的缓冲区大小调整26调整了大约750 MB的开销。。。垃圾收集有多快。。。在750-1024MB的开销中,这很可能是gc的最大开销,因为gc会在执行垃圾收集时挂起所有线程

第二个错误假设:大数据的序列化/传输是性能的衡量标准 与第一个类似,您不是在测试框架,而是在客户机上测试序列化和连接以及分配

最后的话 如果您想测试框架和底层TCP堆栈Kestrel/UVLib与Owin使用的任何东西的性能,请使用一个小样本进行测试。就像回到你好的世界。;并利用http管道,这是您在单个请求中获得最多性能的地方

当您使用控制器时,您还可以测试MVC路由的性能。当通过app.Use…使用单个中间件时,您只需测试Kestrel


在将来进行此类无意义测试之前,我们建议您阅读MSDN上的内容,以便更好地理解为什么您所做的一切都是无意义的,而且它只测量内存和GC,而不测量ASP.NET内核或旧版,.NET Core或.NET Framework

在这种情况下,您似乎只需测量网络速度,还可能测量使用字符串生成器生成大型字符串的性能。@Evk服务器和客户端托管在同一台计算机上。请查看包含localhost:5000的url。您给出的冗长解释涉及不同的内容。但它无法解释为什么一项测试比另一项测试表现更好。垃圾收集、序列化、内存分配是框架提供的服务。任何真实世界的应用程序都将涉及所有这些内容。简单的Hello World Test由你建议是没有用的,因为它不考虑所有这些事情。测试的目的是考虑在ASP.Net内核和自托管API中编写的API如何在繁重的工作负载下执行。可能是垃圾收集的差异,因为.NET Cype和.NETFramework是不同的运行时间,并且可能在GC的工作方式上存在差异。看看techempower基准测试。ASP.NET Core每秒收到125万个请求,而在mono上运行的ASP.NET MVC 5,这比.NET Framework在第11轮中每秒只收到50k个请求要慢得多。两者都在返回Hello World的简单控制器/中间件上。它度量的是框架的实际开销,而不是GC/内存的实际开销
ry在某些方面是瓶颈,即使API只是返回Hello World,垃圾收集也会出现。作为基准​ 建议的asp.net核心每秒处理125万个请求。对于每个请求,必须为“Hello World”分配内存,一旦请求完成,字符串将被取消引用。在某种程度上,GC必须进行清理,因为这里没有大量的请求。此外,benchmark没有比较自托管web api和asp.net核心web api。我在网上没有找到这样的比较。这就是这个问题的真正动机是的,gc将在hello world应用程序中发生,但它只占请求的很小一部分,因为只会收集新一代。但在您的情况下,gc和分配大约占请求时间的95%。这使得你的测试毫无价值。旧ASP.NET的开销太大了。每个请求32kb,而ASP.NET核心中约为2kb。在100万次请求时,这是GBs的分配!