Skip to content
This repository has been archived by the owner on Jul 6, 2018. It is now read-only.

Commit

Permalink
http2: initial benchmarks
Browse files Browse the repository at this point in the history
PR-URL: #180
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
  • Loading branch information
jasnell committed Jul 14, 2017
1 parent ce4c08d commit 734ad72
Show file tree
Hide file tree
Showing 5 changed files with 150 additions and 1 deletion.
6 changes: 6 additions & 0 deletions benchmark/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,12 @@ directory, see [the guide on benchmarks](../doc/guides/writing-and-running-bench
Benchmarks for the <code>http</code> subsystem.
</td>
</tr>
<tr>
<td>http2</td>
<td>
Benchmarks for the <code>http2</code> subsystem.
</td>
</tr>
<tr>
<td>misc</td>
<td>
Expand Down
55 changes: 54 additions & 1 deletion benchmark/_http-benchmarkers.js
Original file line number Diff line number Diff line change
Expand Up @@ -111,10 +111,63 @@ class TestDoubleBenchmarker {
}
}

/**
* HTTP/2 Benchmarker
*/
class H2LoadBenchmarker {
constructor() {
this.name = 'h2load';
this.executable = 'h2load';
const result = child_process.spawnSync(this.executable, ['-h']);
this.present = !(result.error && result.error.code === 'ENOENT');
}

create(options) {
const args = [];
if (typeof options.requests === 'number')
args.push('-n', options.requests);
if (typeof options.clients === 'number')
args.push('-c', options.clients);
if (typeof options.threads === 'number')
args.push('-t', options.threads);
if (typeof options.maxConcurrentStreams === 'number')
args.push('-m', options.maxConcurrentStreams);
if (typeof options.initialWindowSize === 'number')
args.push('-w', options.initialWindowSize);
if (typeof options.sessionInitialWindowSize === 'number')
args.push('-W', options.sessionInitialWindowSize);
if (typeof options.rate === 'number')
args.push('-r', options.rate);
if (typeof options.ratePeriod === 'number')
args.push(`--rate-period=${options.ratePeriod}`);
if (typeof options.duration === 'number')
args.push('-T', options.duration);
if (typeof options.timeout === 'number')
args.push('-N', options.timeout);
if (typeof options.headerTableSize === 'number')
args.push(`--header-table-size=${options.headerTableSize}`);
if (typeof options.encoderHeaderTableSize === 'number') {
args.push(
`--encoder-header-table-size=${options.encoderHeaderTableSize}`);
}
const scheme = options.scheme || 'http';
const host = options.host || '127.0.0.1';
args.push(`${scheme}://${host}:${options.port}${options.path}`);
const child = child_process.spawn(this.executable, args);
return child;
}

processResults(output) {
const rex = /(\d+(?:\.\d+)) req\/s/;
return rex.exec(output)[1];
}
}

const http_benchmarkers = [
new WrkBenchmarker(),
new AutocannonBenchmarker(),
new TestDoubleBenchmarker()
new TestDoubleBenchmarker(),
new H2LoadBenchmarker()
];

const benchmarkers = {};
Expand Down
43 changes: 43 additions & 0 deletions benchmark/http2/respond-with-fd.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
'use strict';

const common = require('../common.js');
const PORT = common.PORT;
const path = require('path');
const fs = require('fs');

const file = path.join(path.resolve(__dirname, '../fixtures'), 'alice.html');

var bench = common.createBenchmark(main, {
requests: [100, 1000, 10000, 100000, 1000000],
streams: [100, 200, 1000],
clients: [1, 2]
}, { flags: ['--expose-http2', '--no-warnings'] });

function main(conf) {

fs.open(file, 'r', (err, fd) => {
if (err)
throw err;

const n = +conf.requests;
const m = +conf.streams;
const c = +conf.clients;
const http2 = require('http2');
const server = http2.createServer();
server.on('stream', (stream) => {
stream.respondWithFD(fd);
stream.on('error', (err) => {});
});
server.listen(PORT, () => {
bench.http({
path: '/',
requests: n,
maxConcurrentStreams: m,
clients: c,
threads: c
}, () => server.close());
});

});

}
38 changes: 38 additions & 0 deletions benchmark/http2/simple.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
'use strict';

const common = require('../common.js');
const PORT = common.PORT;

const path = require('path');
const fs = require('fs');

const file = path.join(path.resolve(__dirname, '../fixtures'), 'alice.html');

var bench = common.createBenchmark(main, {
requests: [100, 1000, 10000, 100000],
streams: [100, 200, 1000],
clients: [1, 2]
}, { flags: ['--expose-http2', '--no-warnings'] });

function main(conf) {
const n = +conf.requests;
const m = +conf.streams;
const c = +conf.clients;
const http2 = require('http2');
const server = http2.createServer();
server.on('stream', (stream) => {
const out = fs.createReadStream(file);
stream.respond();
out.pipe(stream);
stream.on('error', (err) => {});
});
server.listen(PORT, () => {
bench.http({
path: '/',
requests: n,
maxConcurrentStreams: m,
clients: c,
threads: c
}, () => { server.close(); });
});
}
9 changes: 9 additions & 0 deletions doc/guides/writing-and-running-benchmarks.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,14 @@ benchmarker to be used should be specified by providing it as an argument:

`node benchmark/http/simple.js benchmarker=autocannon`

#### HTTP/2 Benchmark Requirements

To run the `http2` benchmarks, the `h2load` benchmarker must be used. The
`h2load` tool is a component of the `nghttp2` project and may be installed
from [nghttp.org][] or built from source.

`node benchmark/http2/simple.js benchmarker=autocannon`

### Benchmark Analysis Requirements

To analyze the results, `R` should be installed. Use one of the available
Expand Down Expand Up @@ -423,3 +431,4 @@ Supported options keys are:
[wrk]: https://github.com/wg/wrk
[t-test]: https://en.wikipedia.org/wiki/Student%27s_t-test#Equal_or_unequal_sample_sizes.2C_unequal_variances
[git-for-windows]: http://git-scm.com/download/win
[nghttp2.org]: http://nghttp2.org

0 comments on commit 734ad72

Please sign in to comment.