论 HTTP 性能，Go 与 .NET Core 一争雌雄
Golang .NET
![](/data/attachment/album/201710/06/111305ltswozo3cmicl3z6.png)


朋友们，你们好！


近来，我听到了大量的关于新出的 .NET Core 和其性能的讨论，尤其在 Web 服务方面的讨论更甚。


因为是新出的，我不想立马就比较两个不同的东西，所以我耐心等待，想等发布更稳定的版本后再进行。


本周一（8 月 14 日），微软[发布 .NET Core 2.0 版本](https://blogs.msdn.microsoft.com/dotnet/2017/08/14/announcing-net-core-2-0/)，因此，我准备开始。您们认为呢？


如前面所提的，我们会比较它们相同的东西，比如应用程序、预期响应及运行时的稳定性，所以我们不会把像对 JSON 或者 XML 的编码、解码这些烦多的事情加入比较游戏中来，仅仅只会使用简单的文本消息。为了公平起见，我们会分别使用 Go 和 .NET Core 的 [MVC 架构模式](https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller)。


### 参赛选手


[Go](https://golang.org/) （或称 Golang）： 是一种[快速增长](http://www.tiobe.com/tiobe-index/)的开源编程语言，旨在构建出简单、快捷和稳定可靠的应用软件。


用于支持 Go 语言的 MVC web 框架并不多，还好我们找到了 Iris ，可胜任此工作。


[Iris](http://iris-go.com/)： 支持 Go 语言的快速、简单和高效的微型 Web 框架。它为您的下一代网站、API 或分布式应用程序奠定了精美的表现方式和易于使用的基础。


[C#](https://en.wikipedia.org/wiki/C_Sharp_%28programming_language%29)： 是一种通用的、面向对象的编程语言。其开发团队由 [Anders Hejlsberg](https://twitter.com/ahejlsberg) 领导。


[.NET Core](https://www.microsoft.com/net/)： 跨平台，可以在极少时间内开发出高性能的应用程序。


可从 <https://golang.org/dl> 下载 Go ，从 <https://www.microsoft.com/net/core> 下载 .NET Core。


在下载和安装好这些软件后，还需要为 Go 安装 Iris。安装很简单，仅仅只需要打开终端，然后执行如下语句：



```
go get -u github.com/kataras/iris

```

### 基准


#### 硬件


* 处理器： Intel(R) Core(TM) i7–4710HQ CPU @ 2.50GHz 2.50GHz
* 内存： 8.00 GB


#### 软件


* 操作系统： 微软 Windows [10.0.15063 版本]， 电源计划设置为“高性能”
* HTTP 基准工具： <https://github.com/codesenberg/bombardier>， 使用最新的 1.1 版本。
* .NET Core： <https://www.microsoft.com/net/core>， 使用最新的 2.0 版本。
* Iris： <https://github.com/kataras/iris>， 使用基于 [Go 1.8.3](https://golang.org/) 构建的最新 8.3 版本。


两个应用程序都通过请求路径 “api/values/{id}” 返回文本“值”。


##### .NET Core MVC


![](/data/attachment/album/201710/06/111305kfvhsvvawf2o1sc5.png)


Logo 由 [Pablo Iglesias](https://github.com/campusMVP/dotnetCoreLogoPack) 设计。


可以使用 `dotnet new webapi` 命令创建项目，其 `webapi` 模板会为您生成代码，代码包含 `GET` 请求方法的 `返回“值”`。


源代码：



```
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;

namespace netcore_mvc
{
    public class Program
    {
        public static void Main(string[] args)
        {
            BuildWebHost(args).Run();
        }

        public static IWebHost BuildWebHost(string[] args) =>
            WebHost.CreateDefaultBuilder(args)
                .UseStartup<Startup>()
                .Build();
    }
}

```


```
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;

namespace netcore_mvc
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvcCore();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            app.UseMvc();
        }
    }
}

```


```
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;

namespace netcore_mvc.Controllers
{
    // ValuesController is the equivalent
    // `ValuesController` of the Iris 8.3 mvc application.
    [Route("api/[controller]")]
    public class ValuesController : Controller
    {
        // Get handles "GET" requests to "api/values/{id}".
        [HttpGet("{id}")]
        public string Get(int id)
        {
            return "value";
        }

        // Put handles "PUT" requests to "api/values/{id}".
        [HttpPut("{id}")]
        public void Put(int id, [FromBody]string value)
        {
        }

        // Delete handles "DELETE" requests to "api/values/{id}".
        [HttpDelete("{id}")]
        public void Delete(int id)
        {
        }
    }
}

```

运行 .NET Core web 服务项目：



```
$ cd netcore-mvc
$ 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
Application started. Press Ctrl+C to shut down.

```

运行和定位 HTTP 基准工具：



```
$ 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% 2m3s
Done!
Statistics        Avg      Stdev        Max
  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.91MB/s

```

##### Iris MVC


![](/data/attachment/album/201710/06/111305gx85k8pcgchtz8gc.png)


Logo 由 [Santosh Anand](https://github.com/santoshanand) 设计。


源代码：



```
package main

import (
    "github.com/kataras/iris"
    "github.com/kataras/iris/_benchmarks/iris-mvc/controllers"
)

func main() {
    app := iris.New()
    app.Controller("/api/values/{id}", new(controllers.ValuesController))
    app.Run(iris.Addr(":5000"), iris.WithoutVersionChecker)
}

```


```
package controllers

import "github.com/kataras/iris/mvc"

// ValuesController is the equivalent
// `ValuesController` of the .net core 2.0 mvc application.
type ValuesController struct {
    mvc.Controller
}

// Get handles "GET" requests to "api/values/{id}".
func (vc *ValuesController) Get() {
    // id,_ := vc.Params.GetInt("id")
    vc.Ctx.WriteString("value")
}

// Put handles "PUT" requests to "api/values/{id}".
func (vc *ValuesController) Put() {}

// Delete handles "DELETE" requests to "api/values/{id}".
func (vc *ValuesController) Delete() {}

```

运行 Go web 服务项目：



```
$ cd iris-mvc
$ go run main.go
Now listening on: http://localhost:5000
Application started. Press CTRL+C to shut down.

```

运行和定位 HTTP 基准工具：



```
$ 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% 47s
Done!
Statistics        Avg      Stdev        Max
  Reqs/sec    105643.81    7687.79     122564
  Latency        1.18ms   366.55us    22.01ms
  HTTP codes:
    1xx - 0, 2xx - 5000000, 3xx - 0, 4xx - 0, 5xx - 0
    others - 0
  Throughput:    19.65MB/s

```

想通过图片来理解的人，我也把我的屏幕截屏出来了！


请点击[这儿](https://github.com/kataras/iris/tree/master/_benchmarks/screens)可以看到这些屏幕快照。


#### 总结


* 完成 `5000000 个请求`的时间 - 越短越好。
* 请求次数/每秒 - 越大越好。
* 等待时间 — 越短越好。
* 吞吐量 — 越大越好。
* 内存使用 — 越小越好。
* LOC (代码行数) — 越少越好。


.NET Core MVC 应用程序，使用 86 行代码，运行 2 分钟 8 秒，每秒接纳 39311.56 个请求，平均 3.19ms 等待，最大时到 229.73ms，内存使用大约为 126MB（不包括 dotnet 框架）。


Iris MVC 应用程序，使用 27 行代码，运行 47 秒，每秒接纳 105643.71 个请求，平均 1.18ms 等待，最大时到 22.01ms，内存使用大约为 12MB。



> 
> 还有另外一个模板的基准，滚动到底部。
> 
> 
> 


**2017 年 8 月 20 号更新**


[Josh Clark](https://twitter.com/clarkis117) 和 [Scott Hanselman](https://twitter.com/shanselman)在此 [tweet 评论](https://twitter.com/shanselman/status/899005786826788865)上指出，.NET Core `Startup.cs` 文件中 `services.AddMvc();` 这行可以替换为 `services.AddMvcCore();`。我听从他们的意见，修改代码，重新运行基准，该文章的 .NET Core 应用程序的基准输出已经修改。


@topdawgevh @shanselman 他们也在使用 `AddMvc()` 而不是 `AddMvcCore()` ...，难道都不包含中间件？


 —  @clarkis117


@clarkis117 @topdawgevh Cool @MakisMaropoulos @ben*a*adams @davidfowl 我们来看看。认真学习下怎么使用更简单的性能默认值。


 —  @shanselman


@shanselman @clarkis117 @topdawgevh @ben*a*adams @davidfowl @shanselman @ben*a*adams @davidfowl 谢谢您们的反馈意见。我已经修改，更新了结果，没什么不同。对其它的建议，我非常欢迎。


 —  @MakisMaropoulos



> 
> 它有点稍微的不同但相差不大（从 8.61MB/s 到 8.91MB/s）
> 
> 
> 


想要了解跟 `services.AddMvc()` 标准比较结果的，可以点击[这儿](https://github.com/kataras/iris/blob/master/_benchmarks/screens/5m_requests_netcore-mvc.png)。


### 想再多了解点儿吗?


我们再制定一个基准，产生 `1000000 次请求`，这次会通过视图引擎由模板生成 `HTML` 页面。


#### .NET Core MVC 使用的模板



```
using System;

namespace netcore_mvc_templates.Models
{
    public class ErrorViewModel
    {
        public string Title { get; set; }
        public int Code { get; set; }
    }
}

```


```
 using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using netcore_mvc_templates.Models;

namespace netcore_mvc_templates.Controllers
{
    public class HomeController : Controller
    {
        public IActionResult Index()
        {
            return View();
        }

        public IActionResult About()
        {
            ViewData["Message"] = "Your application description page.";

            return View();
        }

        public IActionResult Contact()
        {
            ViewData["Message"] = "Your contact page.";

            return View();
        }

        public IActionResult Error()
        {
            return View(new ErrorViewModel { Title = "Error", Code = 500});
        }
    }
}

```


```
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;

namespace netcore_mvc_templates
{
    public class Program
    {
        public static void Main(string[] args)
        {
            BuildWebHost(args).Run();
        }

        public static IWebHost BuildWebHost(string[] args) =>
            WebHost.CreateDefaultBuilder(args)
                .UseStartup<Startup>()
                .Build();
    }
}

```


```
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;

namespace netcore_mvc_templates
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            /*  An unhandled exception was thrown by the application.
                System.InvalidOperationException: No service for type
                'Microsoft.AspNetCore.Mvc.ViewFeatures.ITempDataDictionaryFactory' has been registered.
                Solution: Use AddMvc() instead of AddMvcCore() in Startup.cs and it will work.
            */
            // services.AddMvcCore();
            services.AddMvc();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            app.UseStaticFiles();

            app.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "default",
                    template: "{controller=Home}/{action=Index}/{id?}");
            });
        }
    }
}

```


```
/*
wwwroot/css
wwwroot/images
wwwroot/js
wwwroot/lib
wwwroot/favicon.ico


Views/Shared/_Layout.cshtml
Views/Shared/Error.cshtml

Views/Home/About.cshtml
Views/Home/Contact.cshtml
Views/Home/Index.cshtml

These files are quite long to be shown in this article but you can view them at: 
https://github.com/kataras/iris/tree/master/_benchmarks/netcore-mvc-templates


```

运行 .NET Core 服务项目：



```
$ cd netcore-mvc-templates
$ dotnet run -c Release
Hosting environment: Production
Content root path: C:\mygopath\src\github.com\kataras\iris\_benchmarks\netcore-mvc-templates
Now listening on: http://localhost:5000
Application started. Press Ctrl+C to shut down.

```

运行 HTTP 基准工具：



```
Bombarding http://localhost:5000 with 1000000 requests using 125 connections
 1000000 / 1000000 [====================================================] 100.00% 1m20s
Done!
Statistics Avg Stdev Max
 Reqs/sec 11738.60 7741.36 125887
 Latency 10.10ms 22.10ms 1.97s
 HTTP codes:
 1xx — 0, 2xx — 1000000, 3xx — 0, 4xx — 0, 5xx — 0
 others — 0
 Throughput: 89.03MB/s

```

#### Iris MVC 使用的模板



```
package controllers

import "github.com/kataras/iris/mvc"

type AboutController struct{ mvc.Controller }

func (c *AboutController) Get() {
    c.Data["Title"] = "About"
    c.Data["Message"] = "Your application description page."
    c.Tmpl = "about.html"
}

```


```
package controllers

import "github.com/kataras/iris/mvc"

type ContactController struct{ mvc.Controller }

func (c *ContactController) Get() {
    c.Data["Title"] = "Contact"
    c.Data["Message"] = "Your contact page."
    c.Tmpl = "contact.html"
}

```


```
package models

// HTTPError a silly structure to keep our error page data.
type HTTPError struct {
    Title string
    Code  int
}

```


```
package controllers

import "github.com/kataras/iris/mvc"

type IndexController struct{ mvc.Controller }

func (c *IndexController) Get() {
    c.Data["Title"] = "Home Page"
    c.Tmpl = "index.html"
}

```


```
package main

import (
    "github.com/kataras/iris/_benchmarks/iris-mvc-templates/controllers"

    "github.com/kataras/iris"
    "github.com/kataras/iris/context"
)

const (
    // templatesDir is the exactly the same path that .NET Core is using for its templates,
    // in order to reduce the size in the repository.
    // Change the "C\\mygopath" to your own GOPATH.
    templatesDir = "C:\\mygopath\\src\\github.com\\kataras\\iris\\_benchmarks\\netcore-mvc-templates\\wwwroot"
)

func main() {
    app := iris.New()
    app.Configure(configure)

    app.Controller("/", new(controllers.IndexController))
    app.Controller("/about", new(controllers.AboutController))
    app.Controller("/contact", new(controllers.ContactController))

    app.Run(iris.Addr(":5000"), iris.WithoutVersionChecker)
}

func configure(app *iris.Application) {
    app.RegisterView(iris.HTML("./views", ".html").Layout("shared/layout.html"))
    app.StaticWeb("/public", templatesDir)
    app.OnAnyErrorCode(onError)
}

type err struct {
    Title string
    Code  int
}

func onError(ctx context.Context) {
    ctx.ViewData("", err{"Error", ctx.GetStatusCode()})
    ctx.View("shared/error.html")
}

```


```
/*
../netcore-mvc-templates/wwwroot/css
../netcore-mvc-templates/wwwroot/images
../netcore-mvc-templates/wwwroot/js
../netcore-mvc-templates/wwwroot/lib
../netcore-mvc-templates/wwwroot/favicon.ico
views/shared/layout.html
views/shared/error.html
views/about.html
views/contact.html
views/index.html
These files are quite long to be shown in this article but you can view them at: 
https://github.com/kataras/iris/tree/master/_benchmarks/iris-mvc-templates
*/


```

运行 Go 服务项目：



```
$ cd iris-mvc-templates
$ go run main.go
Now listening on: http://localhost:5000
Application started. Press CTRL+C to shut down.


```

运行 HTTP 基准工具：



```
Bombarding http://localhost:5000 with 1000000 requests using 125 connections
 1000000 / 1000000 [======================================================] 100.00% 37s
Done!
Statistics Avg Stdev Max
 Reqs/sec 26656.76 1944.73 31188
 Latency 4.69ms 1.20ms 22.52ms
 HTTP codes:
 1xx — 0, 2xx — 1000000, 3xx — 0, 4xx — 0, 5xx — 0
 others — 0
 Throughput: 192.51MB/s

```

#### 总结


* 完成 `1000000 个请求`的时间 - 越短越好。
* 请求次数/每秒 - 越大越好。
* 等待时间 — 越短越好。
* 内存使用 — 越小越好。
* 吞吐量 — 越大越好。


.NET Core MVC 模板应用程序，运行 1 分钟 20 秒，每秒接纳 11738.60 个请求，同时每秒生成 89.03M 页面，平均 10.10ms 等待，最大时到 1.97s，内存使用大约为 193MB（不包括 dotnet 框架）。


Iris MVC 模板应用程序，运行 37 秒，每秒接纳 26656.76 个请求，同时每秒生成 192.51M 页面，平均 1.18ms 等待，最大时到 22.52ms，内存使用大约为 17MB。


### 接下来呢？


[这里](https://github.com/kataras/iris/tree/master/_benchmarks)有上面所示的源代码，请下载下来，在您本地以同样的基准运行，然后把运行结果在这儿给大家分享。


想添加 Go 或 C# .net core WEB 服务框架到列表的朋友请向[这个仓库](https://github.com/kataras/iris)的 `_benchmarks` 目录推送 PR。


我也需要亲自感谢下 [dev.to](https://dev.to/kataras/go-vsnet-core-in-terms-of-http-performance) 团队，感谢把我的这篇文章分享到他们的 Twitter 账户。


感谢大家真心反馈，玩得开心！


#### 更新 : 2017 年 8 月 21 ，周一


很多人联系我，希望看到一个基于 .NET Core 的较低级别 Kestrel 的基准测试文章。


因此我完成了，请点击下面的[链接](https://medium.com/@kataras/iris-go-vs-net-core-kestrel-in-terms-of-http-performance-806195dc93d5)来了解 Kestrel 和 Iris 之间的性能差异，它还包含一个会话存储管理基准！




---


via: <https://hackernoon.com/go-vs-net-core-in-terms-of-http-performance-7535a61b67b8>


作者：[Gerasimos Maropoulos](https://hackernoon.com/@kataras?source=post_header_lockup) 译者：[runningwater](https://github.com/runningwater) 校对：[wxy](https://github.com/wxy)


本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译，[Linux中国](https://linux.cn/) 荣誉推出


OK
![Search icon](https://hackernoon.imgix.net/search-new.png?w=19&h=19)


Hello Friends!

Lately I’ve heard a lot of discussion around the new .NET Core and its performance especially on web servers.

I didn’t want to start comparing two different things, so I did patience for quite long for a more stable version.

This Monday, Microsoft [announced the .NET Core version 2.0](https://blogs.msdn.microsoft.com/dotnet/2017/08/14/announcing-net-core-2-0/?ref=hackernoon.com), so I feel ready to do it! Do you?

As we already mentioned, we will compare two identical things here, in terms of application, the expected response and the stability of their run times, so we will not try to put more things in the game like `JSON`

or `XML`

encoders and decoders, just a simple text message. To achieve a fair comparison we will use the [MVC architecture pattern](https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller?ref=hackernoon.com) on both sides, Go and .NET Core.

[Go](https://golang.org/?ref=hackernoon.com) (or Golang): is a [rapidly growing](http://www.tiobe.com/tiobe-index/?ref=hackernoon.com) open source programming language designed for building simple, fast, and reliable software.

There are not lot of web frameworks for Go with MVC support but, luckily for us Iris does the job.

[Iris](http://iris-go.com/?ref=hackernoon.com): A fast, simple and efficient micro web framework for Go. It provides a beautifully expressive and easy to use foundation for your next website, API, or distributed app.

[C#](https://en.wikipedia.org/wiki/C_Sharp_%28programming_language%29?ref=hackernoon.com): is a general-purpose, object-oriented programming language. Its development team is led by [Anders Hejlsberg](https://twitter.com/ahejlsberg?ref=hackernoon.com).

[.NET Core](https://www.microsoft.com/net/?ref=hackernoon.com): Develop high performance applications in less time, on any platform.

Download Go from [https://golang.org/dl](https://golang.org/dl?ref=hackernoon.com) and .NET Core from [https://www.microsoft.com/net/core](https://www.microsoft.com/net/core?ref=hackernoon.com).

After you’ve download and install these, you will need Iris from Go’s side. Installation is very easy, just open your terminal and execute:

go get -u github.com/kataras/iris

Both of the applications will just return the text “value” on request path “api/values/{id}”.

**.NET Core MVC**


*Logo designed by* *Pablo Iglesias**.*

Created using `dotnet new webapi`

. That `webapi`

template will generate the code for you, including the `return “value”`

on `GET`

method requests.

*Source Code*

*Start the .NET Core web server*











$ cd netcore-mvc$ dotnet run -c ReleaseHosting environment: ProductionContent root path: C:\mygopath\src\github.com\kataras\iris\_benchmarks\netcore-mvcNow listening on: [http://localhost:5000](http://localhost:5000/?ref=hackernoon.com)Application started. Press Ctrl+C to shut down.

*Target and run the HTTP benchmark tool*





















$ bombardier -c 125 -n 5000000 [http://localhost:5000/api/values/5](http://localhost:5000/api/values/5?ref=hackernoon.com)Bombarding [http://localhost:5000/api/values/5](http://localhost:5000/api/values/5?ref=hackernoon.com) with 5000000 requests using 125 connections5000000 / 5000000 [=====================================================] 100.00% 2m3sDone!Statistics Avg Stdev MaxReqs/sec 40226.03 8724.30 161919Latency 3.09ms 1.40ms 169.12msHTTP codes:1xx - 0, 2xx - 5000000, 3xx - 0, 4xx - 0, 5xx - 0others - 0Throughput: 8.91MB/s

**Iris MVC**


Logo designed by [Santosh Anand](https://github.com/santoshanand?ref=hackernoon.com).

*Source Code*

*Start the Go web server*







$ cd iris-mvc$ go run main.goNow listening on: [http://localhost:5000](http://localhost:5000/?ref=hackernoon.com)Application started. Press CTRL+C to shut down.

*Target and run the HTTP benchmark tool*





















$ bombardier -c 125 -n 5000000 [http://localhost:5000/api/values/5](http://localhost:5000/api/values/5?ref=hackernoon.com)Bombarding [http://localhost:5000/api/values/5](http://localhost:5000/api/values/5?ref=hackernoon.com) with 5000000 requests using 125 connections5000000 / 5000000 [======================================================] 100.00% 47sDone!Statistics Avg Stdev MaxReqs/sec 105643.81 7687.79 122564Latency 1.18ms 366.55us 22.01msHTTP codes:1xx - 0, 2xx - 5000000, 3xx - 0, 4xx - 0, 5xx - 0others - 0Throughput: 19.65MB/s

For those who understand better by images, I did print my screen too!

Click [here](https://github.com/kataras/iris/tree/master/_benchmarks/screens?ref=hackernoon.com) to see these screenshots.

`5000000 requests`

- 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).

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.


There is also another benchmark with templates, scroll to the bottom.

**Update 20 August 2017**

As [Josh Clark](https://twitter.com/clarkis117?ref=hackernoon.com) and [Scott Hanselman](https://twitter.com/shanselman?ref=hackernoon.com) pointed out on this [re-twee](https://twitter.com/shanselman/status/899005786826788865?ref=hackernoon.com)t , 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.




It had a small difference but not as huge (8.91MB/s from 8.61MB/s)

For those who want to compare with the standard `services.AddMvc();`

you can see the old output by pressing [here](https://github.com/kataras/iris/blob/master/_benchmarks/screens/5m_requests_netcore-mvc.png?ref=hackernoon.com).

Let’s run one more benchmark, spawn `1000000 requests`

but this time we expect `HTML`

generated by templates via the view engine.

*Start the .NET Core web server*











$ cd netcore-mvc-templates$ dotnet run -c ReleaseHosting environment: ProductionContent root path: C:\mygopath\src\github.com\kataras\iris\_benchmarks\netcore-mvc-templatesNow listening on: [http://localhost:5000](http://localhost:5000/?ref=hackernoon.com)Application started. Press Ctrl+C to shut down.

*Target and run the HTTP benchmark tool*



















Bombarding [http://localhost:5000](http://localhost:5000/?ref=hackernoon.com) with 1000000 requests using 125 connections1000000 / 1000000 [====================================================] 100.00% 1m20sDone!Statistics Avg Stdev MaxReqs/sec 11738.60 7741.36 125887Latency 10.10ms 22.10ms 1.97sHTTP codes:1xx — 0, 2xx — 1000000, 3xx — 0, 4xx — 0, 5xx — 0others — 0Throughput: 89.03MB/s

*Start the Go web server*







$ cd iris-mvc-templates$ go run main.goNow listening on: [http://localhost:5000](http://localhost:5000/?ref=hackernoon.com)Application started. Press CTRL+C to shut down.

*Target and run the HTTP benchmark tool*



















Bombarding [http://localhost:5000](http://localhost:5000/?ref=hackernoon.com) with 1000000 requests using 125 connections1000000 / 1000000 [======================================================] 100.00% 37sDone!Statistics Avg Stdev MaxReqs/sec 26656.76 1944.73 31188Latency 4.69ms 1.20ms 22.52msHTTP codes:1xx — 0, 2xx — 1000000, 3xx — 0, 4xx — 0, 5xx — 0others — 0Throughput: 192.51MB/s

**Summary**

`1000000 requests`

— smaller is better..NET Core MVC with Templates Application ran for **1 minute and 20 seconds** serving **11738.60** requests per second with **89.03MB/s** within **10.10ms** latency in average and **1.97s** max, the memory usage of all these was ~193MB (without the dotnet host).

Iris MVC with Templates Application ran for **37 seconds** serving **26656.76** requests per second with **192.51MB/s** within **1.18ms** latency in average and **22.52ms** max, the memory usage of all these was ~17MB.

Download the example source code from [there](https://github.com/kataras/iris/tree/master/_benchmarks?ref=hackernoon.com) and run the same benchmarks from your machine, then come back here and share your results with the rest of us!

For those who want to add other go or c# .net core web frameworks to the list please push a PR to the `_benchmarks`

folder inside [this repository](https://github.com/kataras/iris?ref=hackernoon.com).

I need to personally thanks the [dev.to](https://dev.to/kataras/go-vsnet-core-in-terms-of-http-performance?ref=hackernoon.com) team for sharing my article at their twitter account, as well.


**Thank you** all for the 100% green feedback, have fun!

A lot of people reached me saying that want to see a new benchmarking article based on the .NET Core’s lower level **Kestrel** this time.

So I did, follow the below link to learn the performance difference between Kestrel and Iris, it contains a sessions storage management benchmark too!



**Iris Go vs .NET Core Kestrel in terms of HTTP performance**_A Fair benchmark between Iris Golang and Kestrel .NET Core (C#)._hackernoon.com

I like the visual effects when **I click the clap button more than once**, do you? It’s simple: just click the clap button. If you feel strongly, click it more **(or just hold it** **down).**