Go vs .NET Core in terms of HTTP performance
By: Gerasimos Maropoulos
Tags: Golang, Aspnet, Iris Web Framework, Benchmark, Web Development

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, 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 on both sides, Go and .NET Core.

Prerequisites

Go (or Golang): is a rapidly growing 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: 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#: is a general-purpose, object-oriented programming language. Its development team is led by Anders Hejlsberg.

.NET Core: Develop high performance applications in less time, on any platform.

Download Go from https://golang.org/dl and .NET Core from https://www.microsoft.com/net/core.

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

Benchmarking

Hardware

Processor: Intel(R) Core(TM) i7–4710HQ CPU @ 2.50GHz 2.50GHz

RAM: 8.00 GB

Software

OS: Microsoft Windows [Version 10.0.15063], power plan is “High performance”

HTTP Benchmark Tool: https://github.com/codesenberg/bombardier, latest version 1.1

.NET Core: https://www.microsoft.com/net/core, latest version 2.0

Iris: https://github.com/kataras/iris, latest version 8.3 built with go1.8.3

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



$ dotnet run -c Release

Hosting environment: Production

Content root path: C:\mygopath\src\github.com\kataras\iris\_benchmarks

etcore-mvc

Now listening on:

Application started. Press Ctrl+C to shut down. $ cd netcore-mvc$ dotnet run -c ReleaseHosting environment: ProductionContent root path: C:\mygopath\src\github.com\kataras\iris\_benchmarks

etcore-mvcNow listening on: http://localhost:5000 Application started. Press Ctrl+C to shut down.

Target and run the HTTP benchmark tool



Bombarding

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 $ bombardier -c 125 -n 5000000 http://localhost:5000/api/values/5 Bombarding http://localhost:5000/api/values/5 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.

Source Code

Start the Go web server



$ go run main.go

Now listening on:

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

Target and run the HTTP benchmark tool



Bombarding

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 $ bombardier -c 125 -n 5000000 http://localhost:5000/api/values/5 Bombarding http://localhost:5000/api/values/5 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 to see these screenshots.

Summary

Time to complete the 5000000 requests - smaller is better.

- smaller is better. Reqs/sec — bigger is better.

Latency — smaller is better

Throughput — bigger is better.

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

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 and Scott Hanselman‏ pointed out on this re-tweet , 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)