From 89d0d5c5de87631de9e4e766335b738d02c838d6 Mon Sep 17 00:00:00 2001 From: kataras Date: Sun, 20 Aug 2017 06:53:15 +0300 Subject: [PATCH] =?UTF-8?q?Update=20the=20benchmarks=20results=20as=20Scot?= =?UTF-8?q?t=20Hanselman=E2=80=8F=20and=20Josh=20Clark=20noted.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit No such a difference (before: 8.61MB/s now: 8.91MB/s). I think we can't do much more, I already removed the heavy parts on the first run... but still I'm open for any suggestions. Thank you for the feedback! Former-commit-id: 0b0c8ba40c8380b530b6c77a5ee75ecfb4357f16 --- _benchmarks/README.md | 25 +++++++++--------- _benchmarks/netcore-mvc/Startup.cs | 2 +- .../500m_requests_netcore-mvc_addmvccore.png | Bin 0 -> 11789 bytes 3 files changed, 14 insertions(+), 13 deletions(-) create mode 100644 _benchmarks/screens/500m_requests_netcore-mvc_addmvccore.png diff --git a/_benchmarks/README.md b/_benchmarks/README.md index fcea4394..2490ee30 100644 --- a/_benchmarks/README.md +++ b/_benchmarks/README.md @@ -15,10 +15,7 @@ ### .NET Core MVC ```bash $ cd netcore-mvc -# Same as dotnet run -c Release -# because of the code and configuration, -# scroll to the bottom for more. -$ dotnet run +$ dotnet run -c Release Hosting environment: Production Content root path: C:\mygopath\src\github.com\kataras\iris\_benchmarks\netcore-mvc Now listening on: http://localhost:5000 @@ -28,15 +25,15 @@ Application started. Press Ctrl+C to shut down. ```bash $ bombardier -c 125 -n 5000000 http://localhost:5000/api/values/5 Bombarding http://localhost:5000/api/values/5 with 5000000 requests using 125 connections - 5000000 / 5000000 [=====================================================================================] 100.00% 2m8s + 5000000 / 5000000 [=====================================================================================] 100.00% 2m3s Done! Statistics Avg Stdev Max - Reqs/sec 39311.56 11744.49 264000 - Latency 3.19ms 1.61ms 229.73ms + Reqs/sec 40226.03 8724.30 161919 + Latency 3.09ms 1.40ms 169.12ms HTTP codes: 1xx - 0, 2xx - 5000000, 3xx - 0, 4xx - 0, 5xx - 0 others - 0 - Throughput: 8.61MB/s + Throughput: 8.91MB/s ``` ### Iris MVC @@ -94,17 +91,21 @@ Click [here](screens) to navigate to the screenshots. * Memory usage - smaller is better. * LOC (Lines Of Code) - smaller is better. -.NET Core MVC Application, written using 86 lines of code, ran for **2 minutes and 8 seconds** serving **39311.56** requests per second within **3.19ms** latency in average and **229.73ms** max, the memory usage of all these was ~126MB (without the dotnet host). +.NET Core MVC Application, written using 86 lines of code, ran for **2 minutes and 3 seconds** serving **40226.03** requests per second within **3.09ms** latency in average and **169.12ms** max, the memory usage of all these was ~123MB (without the dotnet host). Iris MVC Application, written using 27 lines of code, ran for **47 seconds** serving **105643.71** requests per second within **1.18ms** latency in average and **22.01ms** max, the memory usage of all these was ~12MB. Iris Application, written using 22 lines of code, ran for **45 seconds** serving **110809.98** requests per second within **1.13ms** latency in average and **18.02ms** max, the memory usage of all these was ~11MB. -#### Notes for .NET Developers +#### Update: 20 August 2017 -Don't try to tell "you're running from `dotnet run` and don't `dotnet run -c Release`", see the output first: `Hosting environment: Production`. It doesn't matter if you run `dotnet run` without arguments: if the configuration file says production or you don't use `if debug then do that`, then it runs as production. +As [Josh Clark](https://twitter.com/clarkis117) and [Scott Hanselman‏](https://twitter.com/shanselman)‏ pointed out [on this status](https://twitter.com/shanselman/status/899005786826788865), on .NET Core `Startup.cs` file the line with `services.AddMvc();` can be replaced with `services.AddMvcCore();`. I followed their helpful instructions and re-run the benchmarks. The article now contains the latest benchmark output for the .NET Core application with the change both Josh and Scott noted. -Want to put some of your benchmarks here? Go ahead and share your results with the rest of us: +The twitter conversion: https://twitter.com/MakisMaropoulos/status/899113215895982080 + +For those who want to compare with the standard services.AddMvc(); you can see the old output by pressing [here](screens/500m_requests_netcore-mvc.png). + +**Thank you all** for the 100% green feedback, have fun! - https://dev.to/kataras/go-vsnet-core-in-terms-of-http-performance - https://medium.com/@kataras/go-vs-net-core-in-terms-of-http-performance-7535a61b67b8 \ No newline at end of file diff --git a/_benchmarks/netcore-mvc/Startup.cs b/_benchmarks/netcore-mvc/Startup.cs index d6019ede..e6e981e2 100644 --- a/_benchmarks/netcore-mvc/Startup.cs +++ b/_benchmarks/netcore-mvc/Startup.cs @@ -23,7 +23,7 @@ namespace netcore_mvc // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { - services.AddMvc(); + services.AddMvcCore(); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. diff --git a/_benchmarks/screens/500m_requests_netcore-mvc_addmvccore.png b/_benchmarks/screens/500m_requests_netcore-mvc_addmvccore.png new file mode 100644 index 0000000000000000000000000000000000000000..a752d9c4e7547e532c1cd75d7e8f992dfdc99ca6 GIT binary patch literal 11789 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 M-_h47yKNouKU_U>hyVZp literal 0 HcmV?d00001