diff --git a/.gitattributes b/.gitattributes index 05fd0d8e..bae831c3 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,3 +1,4 @@ *.go linguist-language=Go vendor/* linguist-vendored -_examples/* linguist-documentation \ No newline at end of file +_examples/* linguist-documentation +_benchmarks/* linguist-documentation \ No newline at end of file diff --git a/README.md b/README.md index 687f9f6c..ffbd9d3a 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,7 @@ Iris may have reached version 8, but we're not stopping there. We have many feat ### 📑 Table of contents * [Installation](#-installation) -* [Latest changes](https://github.com/kataras/iris/blob/master/HISTORY.md#mo-14-august-2017--v826) +* [Latest changes](https://github.com/kataras/iris/blob/master/HISTORY.md#fr-18-august-2017--v830) * [Learn](#-learn) * [HTTP Listening](_examples/#http-listening) * [Configuration](_examples/#configuration) diff --git a/_benchmarks/README.md b/_benchmarks/README.md new file mode 100644 index 00000000..814f2b55 --- /dev/null +++ b/_benchmarks/README.md @@ -0,0 +1,101 @@ +## 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] +* 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](https://golang.org) + +## Results + +### .NET Core MVC +```bash +$ cd netcore-mvc +$ dotnet run +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. +``` + +```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% 2m39s +Done! +Statistics Avg Stdev Max + Reqs/sec 31532.63 10360.09 259792 + Latency 3.99ms 2.32ms 297.21ms + HTTP codes: + 1xx - 0, 2xx - 5000000, 3xx - 0, 4xx - 0, 5xx - 0 + others - 0 + Throughput: 6.89MB/s +``` +> 127210K Memory (private working set) + +### Iris MVC +```bash +$ cd iris-mvc +$ go run main.go +Now listening on: http://localhost:5000 +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% 58s +Done! +Statistics Avg Stdev Max + Reqs/sec 86087.86 3432.38 93833 + Latency 1.45ms 464.12us 42.53ms + HTTP codes: + 1xx - 0, 2xx - 5000000, 3xx - 0, 4xx - 0, 5xx - 0 + others - 0 + Throughput: 16.01MB/s +``` +> 11816K Memory (private working set) + +### Iris +```bash +$ cd iris +$ go run main.go +Now listening on: http://localhost:5000 +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% 48s +Done! +Statistics Avg Stdev Max + Reqs/sec 102987.54 8333.43 120069 + Latency 1.21ms 369.71us 23.52ms + HTTP codes: + 1xx - 0, 2xx - 5000000, 3xx - 0, 4xx - 0, 5xx - 0 + others - 0 + Throughput: 19.15MB/s +``` +> 11040K Memory (private working set) + +Click [here](screens) to navigate to the screenshots. + +#### Summary + +* Time to complete the `5000000 requests` - 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 39 seconds** serving **31532.63** requests per second and **3.99ms** latency in average and **297.21ms** max, the memory usage of all these was 127MB (without the dotnet host). + +Iris MVC Application, written using 27 lines of code, ran for **58 seconds** serving **86087.86** requests per second and **1.45ms** latency in average and **42.53ms** max, the memory usage of all these was 12MB. + +Iris Application, written using 22 lines of code, ran for **48 seconds** serving **102987.54** requests per second and **1.21ms** latency in average and **23.52ms** max, the memory usage of all these was 11MB. \ No newline at end of file diff --git a/_benchmarks/iris-mvc/controllers/values_controller.go b/_benchmarks/iris-mvc/controllers/values_controller.go new file mode 100644 index 00000000..229492a7 --- /dev/null +++ b/_benchmarks/iris-mvc/controllers/values_controller.go @@ -0,0 +1,21 @@ +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.Writef("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() {} diff --git a/_benchmarks/iris-mvc/main.go b/_benchmarks/iris-mvc/main.go new file mode 100644 index 00000000..5d020110 --- /dev/null +++ b/_benchmarks/iris-mvc/main.go @@ -0,0 +1,12 @@ +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")) +} diff --git a/_benchmarks/iris/main.go b/_benchmarks/iris/main.go new file mode 100644 index 00000000..2dee7991 --- /dev/null +++ b/_benchmarks/iris/main.go @@ -0,0 +1,28 @@ +package main + +import ( + "github.com/kataras/iris" + "github.com/kataras/iris/context" +) + +func main() { + app := iris.New() + // These handlers are serving the same routes as + // `ValuesController`s of netcore-mvc and iris-mvc applications do. + app.Get("/api/values/{id}", getHandler) + app.Put("/api/values/{id}", putHandler) + app.Delete("/api/values/{id}", delHandler) + app.Run(iris.Addr(":5000")) +} + +// getHandler handles "GET" requests to "api/values/{id}". +func getHandler(ctx context.Context) { + // id,_ := vc.Params.GetInt("id") + ctx.Writef("value") +} + +// putHandler handles "PUT" requests to "api/values/{id}". +func putHandler(ctx context.Context) {} + +// delHandler handles "DELETE" requests to "api/values/{id}". +func delHandler(ctx context.Context) {} diff --git a/_benchmarks/netcore-mvc/Controllers/ValuesController.cs b/_benchmarks/netcore-mvc/Controllers/ValuesController.cs new file mode 100644 index 00000000..8198900f --- /dev/null +++ b/_benchmarks/netcore-mvc/Controllers/ValuesController.cs @@ -0,0 +1,33 @@ +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) + { + } + } +} diff --git a/_benchmarks/netcore-mvc/Program.cs b/_benchmarks/netcore-mvc/Program.cs new file mode 100644 index 00000000..fec87ec1 --- /dev/null +++ b/_benchmarks/netcore-mvc/Program.cs @@ -0,0 +1,25 @@ +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() + .Build(); + } +} diff --git a/_benchmarks/netcore-mvc/Startup.cs b/_benchmarks/netcore-mvc/Startup.cs new file mode 100644 index 00000000..d6019ede --- /dev/null +++ b/_benchmarks/netcore-mvc/Startup.cs @@ -0,0 +1,35 @@ +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.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.UseMvc(); + } + } +} diff --git a/_benchmarks/netcore-mvc/appsettings.json b/_benchmarks/netcore-mvc/appsettings.json new file mode 100644 index 00000000..3aeec781 --- /dev/null +++ b/_benchmarks/netcore-mvc/appsettings.json @@ -0,0 +1,15 @@ +{ + "Logging": { + "IncludeScopes": false, + "Debug": { + "LogLevel": { + "Default": "Error" + } + }, + "Console": { + "LogLevel": { + "Default": "Error" + } + } + } +} diff --git a/_benchmarks/netcore-mvc/netcore-mvc.csproj b/_benchmarks/netcore-mvc/netcore-mvc.csproj new file mode 100644 index 00000000..89f574c3 --- /dev/null +++ b/_benchmarks/netcore-mvc/netcore-mvc.csproj @@ -0,0 +1,19 @@ + + + + netcoreapp2.0 + + + + + + + + + + + + + + + diff --git a/_benchmarks/screens/500m_requests_iris-mvc.png b/_benchmarks/screens/500m_requests_iris-mvc.png new file mode 100644 index 00000000..7f75d52b Binary files /dev/null and b/_benchmarks/screens/500m_requests_iris-mvc.png differ diff --git a/_benchmarks/screens/500m_requests_iris.png b/_benchmarks/screens/500m_requests_iris.png new file mode 100644 index 00000000..bb6a2579 Binary files /dev/null and b/_benchmarks/screens/500m_requests_iris.png differ diff --git a/_benchmarks/screens/500m_requests_netcore-mvc.png b/_benchmarks/screens/500m_requests_netcore-mvc.png new file mode 100644 index 00000000..13b92c94 Binary files /dev/null and b/_benchmarks/screens/500m_requests_netcore-mvc.png differ