1# Benchmarks 2 3A simple benchmark of Simple-Web-Server and a few similar web libraries. 4 5Details: 6* Linux distribution: Debian Testing (2019-07-29) 7* Linux kernel: 4.19.0-1-amd64 8* CPU: Intel(R) Core(TM) i7-2600 CPU @ 3.40GHz 9* CPU cores: 4 10* The HTTP load generator [httperf](https://github.com/httperf/httperf) is used 11to create the benchmark results, with the following arguments: 12```sh 13httperf --server=localhost --port=3000 --uri=/ --num-conns=20000 --num-calls=200 14``` 15 16The response messages were made identical. 17 18## Express 19 20[Express](https://expressjs.com/) is a popular Node.js web framework. 21 22Versions: 23* Node: v10.15.2 24* Express: 4.17.1 25 26Code: 27```js 28const express = require('express'); 29const app = express(); 30 31app.get('/', (req, res) => { 32 res.removeHeader('X-Powered-By'); 33 res.removeHeader('Connection'); 34 res.end('Hello World!') 35}); 36 37const port = 3000; 38app.listen(port, () => console.log(`Example app listening on port ${port}!`)); 39``` 40 41Execution: 42```sh 43NODE_ENV=production node index.js 44``` 45 46Example results (13659.7 req/s): 47```sh 48httperf --client=0/1 --server=localhost --port=3000 --uri=/ --send-buffer=4096 --recv-buffer=16384 --num-conns=20000 --num-calls=200 49httperf: warning: open file limit > FD_SETSIZE; limiting max. # of open files to FD_SETSIZE 50Maximum connect burst length: 1 51 52Total: connections 20000 requests 40000 replies 20000 test-duration 2.928 s 53 54Connection rate: 6829.9 conn/s (0.1 ms/conn, <=1 concurrent connections) 55Connection time [ms]: min 0.1 avg 0.1 max 14.8 median 0.5 stddev 0.1 56Connection time [ms]: connect 0.0 57Connection length [replies/conn]: 1.000 58 59Request rate: 13659.7 req/s (0.1 ms/req) 60Request size [B]: 62.0 61 62Reply rate [replies/s]: min 0.0 avg 0.0 max 0.0 stddev 0.0 (0 samples) 63Reply time [ms]: response 0.1 transfer 0.0 64Reply size [B]: header 76.0 content 12.0 footer 0.0 (total 88.0) 65Reply status: 1xx=0 2xx=20000 3xx=0 4xx=0 5xx=0 66 67CPU time [s]: user 0.66 system 2.27 (user 22.4% system 77.5% total 99.9%) 68Net I/O: 1414.0 KB/s (11.6*10^6 bps) 69 70Errors: total 20000 client-timo 0 socket-timo 0 connrefused 0 connreset 20000 71Errors: fd-unavail 0 addrunavail 0 ftab-full 0 other 0 72``` 73 74## Hyper 75 76[Hyper](https://hyper.rs/) is a Rust HTTP library that topped the 77[TechEmpower Web Framework Benchmarks results](https://www.techempower.com/benchmarks/#section=data-r18&hw=ph&test=plaintext) in 2019-07-09. 78 79Versions: 80* rustc: 1.38.0-nightly 81* hyper: 0.12 82 83Code (copied from 84https://github.com/hyperium/hyper/blob/0.12.x/examples/hello.rs, but removed `pretty_env_logger` 85calls due to compilation issues): 86```rust 87#![deny(warnings)] 88extern crate hyper; 89// extern crate pretty_env_logger; 90 91use hyper::{Body, Request, Response, Server}; 92use hyper::service::service_fn_ok; 93use hyper::rt::{self, Future}; 94 95fn main() { 96 // pretty_env_logger::init(); 97 let addr = ([127, 0, 0, 1], 3000).into(); 98 99 let server = Server::bind(&addr) 100 .serve(|| { 101 // This is the `Service` that will handle the connection. 102 // `service_fn_ok` is a helper to convert a function that 103 // returns a Response into a `Service`. 104 service_fn_ok(move |_: Request<Body>| { 105 Response::new(Body::from("Hello World!")) 106 }) 107 }) 108 .map_err(|e| eprintln!("server error: {}", e)); 109 110 println!("Listening on http://{}", addr); 111 112 rt::run(server); 113} 114``` 115 116Compilation and run: 117```sh 118cargo run --release 119``` 120 121Example results (60712.3 req/s): 122```sh 123httperf --client=0/1 --server=localhost --port=3000 --uri=/ --send-buffer=4096 --recv-buffer=16384 --num-conns=20000 --num-calls=200 124httperf: warning: open file limit > FD_SETSIZE; limiting max. # of open files to FD_SETSIZE 125Maximum connect burst length: 1 126 127Total: connections 20000 requests 4000000 replies 4000000 test-duration 65.884 s 128 129Connection rate: 303.6 conn/s (3.3 ms/conn, <=1 concurrent connections) 130Connection time [ms]: min 3.0 avg 3.3 max 11.3 median 3.5 stddev 0.3 131Connection time [ms]: connect 0.0 132Connection length [replies/conn]: 200.000 133 134Request rate: 60712.3 req/s (0.0 ms/req) 135Request size [B]: 62.0 136 137Reply rate [replies/s]: min 58704.0 avg 60732.7 max 62587.7 stddev 1021.7 (13 samples) 138Reply time [ms]: response 0.0 transfer 0.0 139Reply size [B]: header 76.0 content 12.0 footer 0.0 (total 88.0) 140Reply status: 1xx=0 2xx=4000000 3xx=0 4xx=0 5xx=0 141 142CPU time [s]: user 15.91 system 49.97 (user 24.1% system 75.8% total 100.0%) 143Net I/O: 8893.4 KB/s (72.9*10^6 bps) 144 145Errors: total 0 client-timo 0 socket-timo 0 connrefused 0 connreset 0 146Errors: fd-unavail 0 addrunavail 0 ftab-full 0 other 0 147``` 148 149## Simple-Web-Server 150 151In these simplistic tests, the performance of Simple-Web-Server is similar to 152the Hyper Rust HTTP library, although Hyper seems to be slightly faster more 153often than not. 154 155Versions: 156* g++: 9.1.0 157 158Code (modified `http_examples.cpp`): 159```c++ 160#include "server_http.hpp" 161 162using HttpServer = SimpleWeb::Server<SimpleWeb::HTTP>; 163 164int main() { 165 HttpServer server; 166 server.config.port = 3000; 167 168 server.default_resource["GET"] = [](std::shared_ptr<HttpServer::Response> response, std::shared_ptr<HttpServer::Request> /*request*/) { 169 response->write("Hello World!", {{"Date", SimpleWeb::Date::to_string(std::chrono::system_clock::now())}}); 170 }; 171 172 server.start(); 173} 174``` 175 176Build, compilation and run: 177```sh 178mkdir build && cd build 179CXX=g++-9 CXXFLAGS="-O2 -DNDEBUG -flto" cmake .. 180make 181./http_examples 182``` 183 184Example results (60596.3 req/s): 185```sh 186httperf --client=0/1 --server=localhost --port=3000 --uri=/ --send-buffer=4096 --recv-buffer=16384 --num-conns=20000 --num-calls=200 187httperf: warning: open file limit > FD_SETSIZE; limiting max. # of open files to FD_SETSIZE 188Maximum connect burst length: 1 189 190Total: connections 20000 requests 4000000 replies 4000000 test-duration 66.011 s 191 192Connection rate: 303.0 conn/s (3.3 ms/conn, <=1 concurrent connections) 193Connection time [ms]: min 3.2 avg 3.3 max 8.0 median 3.5 stddev 0.0 194Connection time [ms]: connect 0.0 195Connection length [replies/conn]: 200.000 196 197Request rate: 60596.3 req/s (0.0 ms/req) 198Request size [B]: 62.0 199 200Reply rate [replies/s]: min 60399.6 avg 60596.9 max 60803.8 stddev 130.9 (13 samples) 201Reply time [ms]: response 0.0 transfer 0.0 202Reply size [B]: header 76.0 content 12.0 footer 0.0 (total 88.0) 203Reply status: 1xx=0 2xx=4000000 3xx=0 4xx=0 5xx=0 204 205CPU time [s]: user 16.07 system 49.93 (user 24.3% system 75.6% total 100.0%) 206Net I/O: 8876.4 KB/s (72.7*10^6 bps) 207 208Errors: total 0 client-timo 0 socket-timo 0 connrefused 0 connreset 0 209Errors: fd-unavail 0 addrunavail 0 ftab-full 0 other 0 210``` 211