update benchmarks and use throng on expressjs for better performance

21 nov 2017- linux version with ubuntu 17.10 and kernel 4.14, all libraries and software updated to their latest versions.

Former-commit-id: 8f8e07838a9a99825555fcbb30f23ac9ee55f685
This commit is contained in:
Gerasimos (Makis) Maropoulos 2017-11-21 11:35:31 +02:00 committed by GitHub
commit 1a595d4ece
37 changed files with 236 additions and 86 deletions

View File

@ -12,14 +12,14 @@ Iris provides a beautifully expressive and easy to use foundation for your next
Learn what [others say about Iris](https://www.youtube.com/watch?v=jGx0LkuUs4A) and [star](https://github.com/kataras/iris/stargazers) this github repository to stay [up to date](https://facebook.com/iris.framework).
[![Iris vs .NET Core(C#) vs Node.js (Express)](https://iris-go.com/images/benchmark-new-gray.png)](_benchmarks)
[![Iris vs .NET Core(C#) vs Node.js (Express)](https://iris-go.com/images/benchmark-new.png)](_benchmarks/README_UNIX.md)
<details>
<summary>Benchmarks from third-party source over the rest web frameworks</summary>
![Comparison with other frameworks](https://raw.githubusercontent.com/smallnest/go-web-framework-benchmark/4db507a22c964c9bc9774c5b31afdc199a0fe8b7/benchmark.png)
_Updated at: [Friday, 29 September 2017](_benchmarks)_
_Updated at: [Tuesday, 21 November 2017](_benchmarks/README_UNIX.md)_
</details>
## Built with ♥️

View File

@ -0,0 +1,61 @@
![Iris vs .NET Core(C#) vs Node.js (Express)](https://iris-go.com/images/benchmark-new.png)]
## Hardware
* [Processor](screens/unix/system_info_cpu.png): Intel(R) Core(TM) **i7-4710HQ** CPU @ 2.50GHz
* [RAM](screens/unix/system_info_ram.png): **8.00 GB**
## Software
* OS: Linux **Ubuntu** [Version **17.10**] with latest kernel version **4.14.0-041400-generic x86_64 GNU/Linux**
* HTTP Benchmark Tool: https://github.com/codesenberg/bombardier, latest version **1.1**
* **Iris [Go]**: https://github.com/kataras/iris, latest version **8.5.7** built with [go1.9.2](https://golang.org)
* **.NET Core [C#]**: https://www.microsoft.com/net/core, latest version **2.0.2**
* **Node.js (express + throng) [Javascript]**: https://nodejs.org/, latest version **9.2.0**, express: https://github.com/expressjs/express latest version **4.16.0** and [throng](https://www.npmjs.com/package/throng) latest version **4.0.0**
Go ahead to the [README.md](README.md) and read how you can reproduce the benchmarks. Don't be scary it's actually very easy, you can do these things as well!
## Results
* Throughput - `bigger is better`.
* Reqs/sec (Requests Per Second in Average) - `bigger is better`.
* Latency - `smaller is better`.
* Time To Complete - `smaller is better`.
* Total Requests in this fortune are all 1 million, in order to be easier to do the graph later on.
### Native
| Name | Throughput | Reqs/sec | Latency | Time To Complete | Total Requests |
|-------|:-----------|:--------|:-------------|---------|------|------|
| Iris | **29.31MB/s** | 157628 | 791.58us | 6s | 1000000 |
| Kestrel | **25.28MB/s** | 139642 | 0.89ms | 7s | 1000000 |
| Node.js | **13.69MB/s** | 50907 | 2.45ms | 19s | 1000000 |
| Iris with Sessions | **22.37MB/s** | 71922 | 1.74ms | 14s | 1000000 |
| Kestrel with Sessions | **14.51MB/s** | 31102 | 4.02ms | 32s | 1000000 |
| Node.js with Sessions | **5.08MB/s** | 19358 | 6.48ms | 51s | 1000000 |
> each test has its own screenshot, click [here](screens/unix) to explore
### MVC (Model View Controller)
| Name | Throughput | Reqs/sec | Latency | Time To Complete | Total Requests |
|-------|:-----------|:--------|:-------------|---------|------|
| Iris MVC | **26.39MB/s** | 141868 | 0.88ms | 7s | 1000000 |
| .Net Core MVC | **11.99MB/s** | 54418 | 2.30ms | 18s | 1000000 |
| - | - | - | - | - | - |
| Iris MVC with Templates | **136.58MB/s** | 18933 | 6.60ms | 52s | 1000000 |
| .Net Core MVC with Templates | **88.95MB/s** | 12347 | 10.12ms | 1m21s | 1000000 |
| - | - | - | - | - | - |
> nodejs express does not contain any MVC features
### Updates
- 21 November 2017: initial run and publish
## Articles (ms windows OS)
- https://hackernoon.com/go-vs-net-core-in-terms-of-http-performance-7535a61b67b8
- https://hackernoon.com/iris-go-vs-net-core-kestrel-in-terms-of-http-performance-806195dc93d5
**Thank you all** for the 100% green feedback, have fun!

View File

@ -1,26 +0,0 @@
process.env.NODE_ENV = 'production';
const express = require('express');
const app = express();
const session = require('express-session');
// Use the session middleware
app.use(session({ secret: '.cookiesession.id', resave: true, saveUninitialized: false, cookie: { secure: true, maxAge: 60000 } }));
app.get('/setget', function (req, res) {
req.session.key = 'value';
var value = req.session.key;
if (value == '') {
res.send('NOT_OK');
return;
}
res.send(value);
});
app.listen(5000, function () {
console.log(
'Now listening on: http://localhost:5000\nApplication started. Press CTRL+C to shut down.'
)
});

View File

@ -0,0 +1,33 @@
process.env.NODE_ENV = 'production';
const express = require('express');
const app = express();
const session = require('express-session');
const createWorker = require('throng');
const MemoryStore = require('session-memory-store')(session);
createWorker(createWebServer)
function createWebServer() {
// Use the session middleware with the memory-store as
// recommended for production local use, like with iris and netcore.
app.use(session({ store: new MemoryStore({expires: 1*60, checkperiod: 1*60}), secret: '.cookiesession.id', resave: true, saveUninitialized: false, cookie: { secure: true, maxAge: 60000 } }));
app.get('/setget', function (req, res) {
req.session.key = 'value';
var value = req.session.key;
if (value == '') {
res.send('NOT_OK');
return;
}
res.send(value);
});
app.listen(5000, function () {
console.log(
'Now listening on: http://localhost:5000\nApplication started. Press CTRL+C to shut down.'
)
});
}

View File

@ -40,6 +40,11 @@
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz",
"integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg="
},
"clone": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/clone/-/clone-1.0.3.tgz",
"integrity": "sha1-KY1+IjFmD0DAA8LtMUDezz9TCF8="
},
"content-disposition": {
"version": "0.5.2",
"resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz",
@ -213,6 +218,16 @@
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.5.2.tgz",
"integrity": "sha1-1LUFvemUaYfM8PxY2QEP+WB+P6A="
},
"lodash": {
"version": "2.4.2",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-2.4.2.tgz",
"integrity": "sha1-+t2DS5aDBz2hebPq5tnA0VBT9z4="
},
"lodash.defaults": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz",
"integrity": "sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw="
},
"media-typer": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
@ -256,6 +271,22 @@
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz",
"integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk="
},
"node-cache": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/node-cache/-/node-cache-3.2.1.tgz",
"integrity": "sha1-p5WNMqikLZEZziWYZWfqLF+WZ3M=",
"requires": {
"clone": "1.0.3",
"lodash": "4.17.4"
},
"dependencies": {
"lodash": {
"version": "4.17.4",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz",
"integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4="
}
}
},
"on-finished": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
@ -350,6 +381,15 @@
"send": "0.16.0"
}
},
"session-memory-store": {
"version": "0.2.2",
"resolved": "https://registry.npmjs.org/session-memory-store/-/session-memory-store-0.2.2.tgz",
"integrity": "sha1-1GQ48oTPjg7RVE9v1Zk+4Ud8dlY=",
"requires": {
"lodash": "2.4.2",
"node-cache": "3.2.1"
}
},
"setprototypeof": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz",
@ -360,6 +400,14 @@
"resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz",
"integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4="
},
"throng": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/throng/-/throng-4.0.0.tgz",
"integrity": "sha1-mDxroZk7WOroWZmKpof/6I34TBc=",
"requires": {
"lodash.defaults": "4.2.0"
}
},
"type-is": {
"version": "1.6.15",
"resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.15.tgz",

View File

@ -9,6 +9,9 @@
"author": "Gerasimos (Makis) Maropoulos <kataras2006@hotmail.com>",
"license": "ISC",
"dependencies": {
"express": "^4.16.0"
"express": "^4.16.0",
"express-session": "^1.15.6",
"session-memory-store": "^0.2.2",
"throng": "4.0.0"
}
}

View File

@ -0,0 +1,22 @@
process.env.NODE_ENV = 'production';
const express = require('express');
const createWorker = require('throng');
createWorker(createWebServer)
function createWebServer() {
const app = express();
app.get('/api/values/:id', function (req, res) {
res.send('value');
});
app.listen(5000, function () {
console.log(
'Now listening on: http://localhost:5000\nApplication started. Press CTRL+C to shut down.'
)
});
}

View File

@ -192,6 +192,11 @@
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.5.2.tgz",
"integrity": "sha1-1LUFvemUaYfM8PxY2QEP+WB+P6A="
},
"lodash.defaults": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz",
"integrity": "sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw="
},
"media-typer": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
@ -329,6 +334,14 @@
"resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz",
"integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4="
},
"throng": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/throng/-/throng-4.0.0.tgz",
"integrity": "sha1-mDxroZk7WOroWZmKpof/6I34TBc=",
"requires": {
"lodash.defaults": "4.2.0"
}
},
"type-is": {
"version": "1.6.15",
"resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.15.tgz",

View File

@ -10,6 +10,6 @@
"license": "ISC",
"dependencies": {
"express": "^4.16.0",
"express-session": "^1.15.6"
"throng": "4.0.0"
}
}
}

View File

@ -1,14 +0,0 @@
process.env.NODE_ENV = 'production';
const express = require('express');
const app = express();
app.get('/api/values/:id', function (req, res) {
res.send('value');
});
app.listen(5000, function () {
console.log(
'Now listening on: http://localhost:5000\nApplication started. Press CTRL+C to shut down.'
)
});

View File

@ -0,0 +1,27 @@
package controllers
import "github.com/kataras/iris/mvc"
type HomeController struct{ mvc.C }
func (c *HomeController) Get() mvc.Result {
return mvc.View{Name: "index.html"}
}
func (c *HomeController) GetAbout() mvc.Result {
return mvc.View{
Name: "about.html",
Data: map[string]interface{}{
"Title": "About Page",
"Message": "Your application description page."},
}
}
func (c *HomeController) GetContact() mvc.Result {
return mvc.View{
Name: "contact.html",
Data: map[string]interface{}{
"Title": "Contact Page",
"Message": "Your application description page."},
}
}

View File

@ -1,14 +0,0 @@
package controllers
import "github.com/kataras/iris/mvc"
type IndexControllerHeavy struct{ mvc.C }
func (c *IndexControllerHeavy) Get() mvc.View {
return mvc.View{
Name: "index.html",
Data: map[string]interface{}{
"Title": "Home Page",
},
}
}

View File

@ -8,28 +8,29 @@ import (
)
const (
// templatesDir is the exactly the same path that .NET Core is using for its templates,
// publicDir 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"
// publicDir = "C:\\mygopath\\src\\github.com\\kataras\\iris\\_benchmarks\\netcore-mvc-templates\\wwwroot"
publicDir = "/home/kataras/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.Controller("/", new(controllers.IndexController))
// app.Controller("/about", new(controllers.AboutController))
// app.Controller("/contact", new(controllers.ContactController))
app.Controller("/", new(controllers.HomeController))
// 24 August 2017: Iris has a built'n version updater but we don't need it
// when benchmarking...
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.StaticWeb("/public", publicDir)
app.OnAnyErrorCode(onError)
}

View File

@ -5,13 +5,19 @@ import "github.com/kataras/iris/mvc"
// ValuesController is the equivalent
// `ValuesController` of the .net core 2.0 mvc application.
type ValuesController struct {
mvc.Controller
mvc.C
}
// Get handles "GET" requests to "api/values/{id}".
/* on windows tests(older) the Get was:
func (vc *ValuesController) Get() {
// id,_ := vc.Params.GetInt("id")
vc.Ctx.WriteString("value")
// vc.Ctx.WriteString("value")
}
but as Iris is always going better, now supports return values as well*/
// Get handles "GET" requests to "api/values/{id}".
func (vc *ValuesController) Get() string {
return "value"
}
// Put handles "PUT" requests to "api/values/{id}".

View File

@ -11,7 +11,5 @@ func main() {
ctx.WriteString("value")
})
// 24 August 2017: Iris has a built'n version updater but we don't need it
// when benchmarking...
app.Run(iris.Addr(":5000"), iris.WithoutVersionChecker)
}

View File

@ -17,6 +17,7 @@ namespace netcore_mvc_templates.Controllers
public IActionResult About()
{
ViewData["Title"] = "About Page";
ViewData["Message"] = "Your application description page.";
return View();
@ -24,6 +25,7 @@ namespace netcore_mvc_templates.Controllers
public IActionResult Contact()
{
ViewData["Title"] = "Contact Page";
ViewData["Message"] = "Your contact page.";
return View();

View File

@ -1,7 +1,4 @@
@{
ViewData["Title"] = "About";
}
<h2>@ViewData["Title"]</h2>
<h2>@ViewData["Title"]</h2>
<h3>@ViewData["Message"]</h3>
<p>Use this area to provide additional information.</p>

View File

@ -1,7 +1,4 @@
@{
ViewData["Title"] = "Contact";
}
<h2>@ViewData["Title"]</h2>
<h2>@ViewData["Title"]</h2>
<h3>@ViewData["Message"]</h3>
<address>

View File

@ -1,8 +1,4 @@
@{
ViewData["Title"] = "Home Page";
}
<div id="myCarousel" class="carousel slide" data-ride="carousel" data-interval="6000">
<div id="myCarousel" class="carousel slide" data-ride="carousel" data-interval="6000">
<ol class="carousel-indicators">
<li data-target="#myCarousel" data-slide-to="0" class="active"></li>
<li data-target="#myCarousel" data-slide-to="1"></li>

View File

@ -5,7 +5,7 @@
</PropertyGroup>
<ItemGroup>
<Folder Include="wwwroot\" />
<Folder Include="wwwroot/" />
</ItemGroup>
<ItemGroup>

Binary file not shown.

After

Width:  |  Height:  |  Size: 146 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 152 KiB