GeezerVison is showing github.com — benchmark: add simple https benchmark · nodejs/node@7aedda9
File treeExpand file treeCollapse file tree Open diff view settings Expand file treeCollapse file tree Open diff view settings Collapse file Copy file name to clipboardExpand all lines: benchmark/_http-benchmarkers.js +9-5Lines changed: 9 additions & 5 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -29,7 +29,8 @@ class AutocannonBenchmarker { | 29 | 29 | for (const field in options.headers) { | 30 | 30 | args.push('-H', `${field}=${options.headers[field]}`); | 31 | 31 | } | 32 | | - args.push(`http://127.0.0.1:${options.port}${options.path}`); | | 32 | + const scheme = options.scheme || 'http'; | | 33 | + args.push(`${scheme}://127.0.0.1:${options.port}${options.path}`); | 33 | 34 | const child = child_process.spawn(this.executable, args); | 34 | 35 | return child; | 35 | 36 | } | @@ -60,11 +61,12 @@ class WrkBenchmarker { | 60 | 61 | const duration = typeof options.duration === 'number' ? | 61 | 62 | Math.max(options.duration, 1) : | 62 | 63 | options.duration; | | 64 | + const scheme = options.scheme || 'http'; | 63 | 65 | const args = [ | 64 | 66 | '-d', duration, | 65 | 67 | '-c', options.connections, | 66 | 68 | '-t', Math.min(options.connections, require('os').cpus().length || 8), | 67 | | - `http://127.0.0.1:${options.port}${options.path}`, | | 69 | + `${scheme}://127.0.0.1:${options.port}${options.path}`, | 68 | 70 | ]; | 69 | 71 | for (const field in options.headers) { | 70 | 72 | args.push('-H', `${field}: ${options.headers[field]}`); | @@ -90,8 +92,8 @@ class WrkBenchmarker { | 90 | 92 | */ | 91 | 93 | class TestDoubleBenchmarker { | 92 | 94 | constructor(type) { | 93 | | - // `type` is the type of benchmarker. Possible values are 'http' and | 94 | | - // 'http2'. | | 95 | + // `type` is the type of benchmarker. Possible values are 'http', 'https', | | 96 | + // and 'http2'. | 95 | 97 | this.name = `test-double-${type}`; | 96 | 98 | this.executable = path.resolve(__dirname, '_test-double-benchmarker.js'); | 97 | 99 | this.present = fs.existsSync(this.executable); | @@ -101,8 +103,9 @@ class TestDoubleBenchmarker { | 101 | 103 | create(options) { | 102 | 104 | process.env.duration = process.env.duration || options.duration || 5; | 103 | 105 |
| | 106 | + const scheme = options.scheme || 'http'; | 104 | 107 | const env = { | 105 | | - test_url: `http://127.0.0.1:${options.port}${options.path}`, | | 108 | + test_url: `${scheme}://127.0.0.1:${options.port}${options.path}`, | 106 | 109 | ...process.env | 107 | 110 | }; | 108 | 111 |
| @@ -179,6 +182,7 @@ const http_benchmarkers = [ | 179 | 182 | new WrkBenchmarker(), | 180 | 183 | new AutocannonBenchmarker(), | 181 | 184 | new TestDoubleBenchmarker('http'), | | 185 | + new TestDoubleBenchmarker('https'), | 182 | 186 | new TestDoubleBenchmarker('http2'), | 183 | 187 | new H2LoadBenchmarker(), | 184 | 188 | ]; | |
Collapse file Copy file name to clipboardExpand all lines: benchmark/_test-double-benchmarker.js +12-3Lines changed: 12 additions & 3 deletions | Original file line number | Diff line number | Diff line change |
|---|
| 1 | 1 | 'use strict'; | 2 | 2 |
| 3 | 3 | const myModule = process.argv[2]; | 4 | | -if (!['http', 'http2'].includes(myModule)) { | | 4 | +if (!['http', 'https', 'http2'].includes(myModule)) { | 5 | 5 | throw new Error(`Invalid module for benchmark test double: ${myModule}`); | 6 | 6 | } | 7 | 7 |
| | 8 | +let options; | | 9 | +if (myModule === 'https') { | | 10 | + options = { rejectUnauthorized: false }; | | 11 | +} | | 12 | + | 8 | 13 | const http = require(myModule); | 9 | 14 |
| 10 | 15 | const duration = +process.env.duration; | @@ -33,8 +38,12 @@ function request(res, client) { | 33 | 38 | } | 34 | 39 |
| 35 | 40 | function run() { | 36 | | - if (http.get) { // HTTP | 37 | | - http.get(url, request); | | 41 | + if (http.get) { // HTTP or HTTPS | | 42 | + if (options) { | | 43 | + http.get(url, options, request); | | 44 | + } else { | | 45 | + http.get(url, request); | | 46 | + } | 38 | 47 | } else { // HTTP/2 | 39 | 48 | const client = http.connect(url); | 40 | 49 | client.on('error', (e) => { throw e; }); | |
Collapse file Copy file name to clipboard +72Lines changed: 72 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
| | 1 | +'use strict'; | | 2 | + | | 3 | +const fixtures = require('../../test/common/fixtures'); | | 4 | +const https = require('https'); | | 5 | + | | 6 | +const options = { | | 7 | + key: fixtures.readKey('rsa_private.pem'), | | 8 | + cert: fixtures.readKey('rsa_cert.crt') | | 9 | +}; | | 10 | + | | 11 | +const storedBytes = Object.create(null); | | 12 | +const storedBuffer = Object.create(null); | | 13 | + | | 14 | +module.exports = https.createServer(options, (req, res) => { | | 15 | + // URL format: /<type>/<length>/<chunks>/chunkedEnc | | 16 | + const params = req.url.split('/'); | | 17 | + const command = params[1]; | | 18 | + let body = ''; | | 19 | + const arg = params[2]; | | 20 | + const n_chunks = parseInt(params[3], 10); | | 21 | + const chunkedEnc = params.length >= 5 && params[4] === '0' ? false : true; | | 22 | + let status = 200; | | 23 | + | | 24 | + let n, i; | | 25 | + if (command === 'bytes') { | | 26 | + n = ~~arg; | | 27 | + if (n <= 0) | | 28 | + throw new Error('bytes called with n <= 0'); | | 29 | + if (storedBytes[n] === undefined) { | | 30 | + storedBytes[n] = 'C'.repeat(n); | | 31 | + } | | 32 | + body = storedBytes[n]; | | 33 | + } else if (command === 'buffer') { | | 34 | + n = ~~arg; | | 35 | + if (n <= 0) | | 36 | + throw new Error('buffer called with n <= 0'); | | 37 | + if (storedBuffer[n] === undefined) { | | 38 | + storedBuffer[n] = Buffer.allocUnsafe(n); | | 39 | + for (i = 0; i < n; i++) { | | 40 | + storedBuffer[n][i] = 'C'.charCodeAt(0); | | 41 | + } | | 42 | + } | | 43 | + body = storedBuffer[n]; | | 44 | + } else { | | 45 | + status = 404; | | 46 | + body = 'not found\n'; | | 47 | + } | | 48 | + | | 49 | + // example: https://localhost:port/bytes/512/4 | | 50 | + // sends a 512 byte body in 4 chunks of 128 bytes | | 51 | + const len = body.length; | | 52 | + if (chunkedEnc) { | | 53 | + res.writeHead(status, { | | 54 | + 'Content-Type': 'text/plain', | | 55 | + 'Transfer-Encoding': 'chunked' | | 56 | + }); | | 57 | + } else { | | 58 | + res.writeHead(status, { | | 59 | + 'Content-Type': 'text/plain', | | 60 | + 'Content-Length': len.toString() | | 61 | + }); | | 62 | + } | | 63 | + // send body in chunks | | 64 | + if (n_chunks > 1) { | | 65 | + const step = Math.floor(len / n_chunks) || 1; | | 66 | + for (i = 0, n = (n_chunks - 1); i < n; ++i) | | 67 | + res.write(body.slice(i * step, i * step + step)); | | 68 | + res.end(body.slice((n_chunks - 1) * step)); | | 69 | + } else { | | 70 | + res.end(body); | | 71 | + } | | 72 | +}); |
Collapse file Copy file name to clipboard +29Lines changed: 29 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
| | 1 | +'use strict'; | | 2 | +const common = require('../common.js'); | | 3 | + | | 4 | +const bench = common.createBenchmark(main, { | | 5 | + type: ['bytes', 'buffer'], | | 6 | + len: [4, 1024, 102400], | | 7 | + chunks: [1, 4], | | 8 | + c: [50, 500], | | 9 | + chunkedEnc: [1, 0], | | 10 | + benchmarker: ['test-double-https'], | | 11 | + duration: 5 | | 12 | +}); | | 13 | + | | 14 | +function main({ type, len, chunks, c, chunkedEnc, duration }) { | | 15 | + const server = require('../fixtures/simple-https-server.js') | | 16 | + .listen(common.PORT) | | 17 | + .on('listening', () => { | | 18 | + const path = `/${type}/${len}/${chunks}/${chunkedEnc}`; | | 19 | + | | 20 | + bench.http({ | | 21 | + path, | | 22 | + connections: c, | | 23 | + scheme: 'https', | | 24 | + duration | | 25 | + }, () => { | | 26 | + server.close(); | | 27 | + }); | | 28 | + }); | | 29 | +} |
Collapse file Copy file name to clipboardExpand all lines: doc/guides/writing-and-running-benchmarks.md +10-1Lines changed: 10 additions & 1 deletion - Display the source diff
- Display the rich diff
| Original file line number | Diff line number | Diff line change |
|---|
| 4 | 4 |
| 5 | 5 | * [Prerequisites](#prerequisites) | 6 | 6 | * [HTTP Benchmark Requirements](#http-benchmark-requirements) | | 7 | + * [HTTPS Benchmark Requirements](#https-benchmark-requirements) | | 8 | + * [HTTP/2 Benchmark Requirements](#http2-benchmark-requirements) | 7 | 9 | * [Benchmark Analysis Requirements](#benchmark-analysis-requirements) | 8 | 10 | * [Running benchmarks](#running-benchmarks) | 9 | 11 | * [Running individual benchmarks](#running-individual-benchmarks) | @@ -43,13 +45,20 @@ benchmarker to be used should be specified by providing it as an argument: | 43 | 45 |
| 44 | 46 | `node benchmark/http/simple.js benchmarker=autocannon` | 45 | 47 |
| | 48 | +#### HTTPS Benchmark Requirements | | 49 | + | | 50 | +To run the `https` benchmarks, one of `autocannon` or `wrk` benchmarkers must | | 51 | +be used. | | 52 | + | | 53 | +`node benchmark/https/simple.js benchmarker=autocannon` | | 54 | + | 46 | 55 | #### HTTP/2 Benchmark Requirements | 47 | 56 |
| 48 | 57 | To run the `http2` benchmarks, the `h2load` benchmarker must be used. The | 49 | 58 | `h2load` tool is a component of the `nghttp2` project and may be installed | 50 | 59 | from [nghttp2.org][] or built from source. | 51 | 60 |
| 52 | | -`node benchmark/http2/simple.js benchmarker=autocannon` | | 61 | +`node benchmark/http2/simple.js benchmarker=h2load` | 53 | 62 |
| 54 | 63 | ### Benchmark Analysis Requirements | 55 | 64 |
| |
|