xref: /aosp_15_r20/external/ot-br-posix/third_party/Simple-web-server/repo/docs/benchmarks.md (revision 4a64e381480ef79f0532b2421e44e6ee336b8e0d)
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