Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

benchmark, test: test the HTTP benchmark with a dummy benchmarker #12121

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
153 changes: 99 additions & 54 deletions benchmark/_http-benchmarkers.js
Original file line number Diff line number Diff line change
@@ -1,74 +1,119 @@
'use strict';

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

// The port used by servers and wrk
exports.PORT = process.env.PORT || 12346;

function AutocannonBenchmarker() {
this.name = 'autocannon';
this.autocannon_exe = process.platform === 'win32' ?
'autocannon.cmd' :
'autocannon';
const result = child_process.spawnSync(this.autocannon_exe, ['-h']);
this.present = !(result.error && result.error.code === 'ENOENT');
}
class AutocannonBenchmarker {
constructor() {
this.name = 'autocannon';
this.executable = process.platform === 'win32' ?
'autocannon.cmd' :
'autocannon';
const result = child_process.spawnSync(this.executable, ['-h']);
this.present = !(result.error && result.error.code === 'ENOENT');
}

AutocannonBenchmarker.prototype.create = function(options) {
const args = [
'-d', options.duration,
'-c', options.connections,
'-j',
'-n',
`http://127.0.0.1:${options.port}${options.path}`
];
const child = child_process.spawn(this.autocannon_exe, args);
return child;
};
create(options) {
const args = [
'-d', options.duration,
'-c', options.connections,
'-j',
'-n',
`http://127.0.0.1:${options.port}${options.path}`
];
const child = child_process.spawn(this.executable, args);
return child;
}

AutocannonBenchmarker.prototype.processResults = function(output) {
let result;
try {
result = JSON.parse(output);
} catch (err) {
// Do nothing, let next line handle this
processResults(output) {
let result;
try {
result = JSON.parse(output);
} catch (err) {
return undefined;
}
if (!result || !result.requests || !result.requests.average) {
return undefined;
} else {
return result.requests.average;
}
}
if (!result || !result.requests || !result.requests.average) {
return undefined;
} else {
return result.requests.average;
}

class WrkBenchmarker {
constructor() {
this.name = 'wrk';
this.executable = 'wrk';
const result = child_process.spawnSync(this.executable, ['-h']);
this.present = !(result.error && result.error.code === 'ENOENT');
}

create(options) {
const args = [
'-d', options.duration,
'-c', options.connections,
'-t', 8,
`http://127.0.0.1:${options.port}${options.path}`
];
const child = child_process.spawn(this.executable, args);
return child;
}
};

function WrkBenchmarker() {
this.name = 'wrk';
this.regexp = /Requests\/sec:[ \t]+([0-9.]+)/;
const result = child_process.spawnSync('wrk', ['-h']);
this.present = !(result.error && result.error.code === 'ENOENT');
processResults(output) {
const throughputRe = /Requests\/sec:[ \t]+([0-9.]+)/;
const match = output.match(throughputRe);
const throughput = match && +match[1];
if (!isFinite(throughput)) {
return undefined;
} else {
return throughput;
}
}
}

WrkBenchmarker.prototype.create = function(options) {
const args = [
'-d', options.duration,
'-c', options.connections,
'-t', 8,
`http://127.0.0.1:${options.port}${options.path}`
];
const child = child_process.spawn('wrk', args);
return child;
};
/**
* Simple, single-threaded benchmarker for testing if the benchmark
* works
*/
class TestDoubleBenchmarker {
constructor() {
this.name = 'test-double';
this.executable = path.resolve(__dirname, '_test-double-benchmarker.js');
this.present = fs.existsSync(this.executable);
}

create(options) {
const child = child_process.fork(this.executable, {
silent: true,
env: {
duration: options.duration,
connections: options.connections,
path: `http://127.0.0.1:${options.port}${options.path}`
}
});
return child;
}

WrkBenchmarker.prototype.processResults = function(output) {
const match = output.match(this.regexp);
const result = match && +match[1];
if (!isFinite(result)) {
return undefined;
} else {
return result;
processResults(output) {
let result;
try {
result = JSON.parse(output);
} catch (err) {
return undefined;
}
return result.throughput;
}
};
}

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

const benchmarkers = {};

Expand Down
7 changes: 7 additions & 0 deletions benchmark/_test-double-benchmarker.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
'use strict';

const http = require('http');

http.get(process.env.path, function() {
console.log(JSON.stringify({throughput: 1}));
});
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@

var http = require('http');

var port = parseInt(process.env.PORT || 8000);

var fixed = 'C'.repeat(20 * 1024);
var storedBytes = Object.create(null);
var storedBuffer = Object.create(null);
Expand All @@ -22,7 +20,7 @@ if (useDomains) {
gdom.enter();
}

var server = module.exports = http.createServer(function(req, res) {
module.exports = http.createServer(function(req, res) {
if (useDomains) {
var dom = domain.create();
dom.add(req);
Expand Down Expand Up @@ -142,8 +140,3 @@ var server = module.exports = http.createServer(function(req, res) {
res.end(body);
}
});

server.listen(port, function() {
if (module === require.main)
console.error('Listening at http://127.0.0.1:' + port + '/');
});
4 changes: 2 additions & 2 deletions benchmark/http/_chunky_http_client.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@ var test = require('../../test/common.js');

var bench = common.createBenchmark(main, {
len: [1, 4, 8, 16, 32, 64, 128],
num: [5, 50, 500, 2000],
n: [5, 50, 500, 2000],
type: ['send'],
});


function main(conf) {
var len = +conf.len;
var num = +conf.num;
var num = +conf.n;
var todo = [];
var headers = [];
// Chose 7 because 9 showed "Connection error" / "Connection closed"
Expand Down
6 changes: 3 additions & 3 deletions benchmark/http/bench-parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,17 @@ const kOnMessageComplete = HTTPParser.kOnMessageComplete | 0;
const CRLF = '\r\n';

const bench = common.createBenchmark(main, {
fields: [4, 8, 16, 32],
len: [4, 8, 16, 32],
n: [1e5],
});


function main(conf) {
const fields = conf.fields >>> 0;
const len = conf.len >>> 0;
const n = conf.n >>> 0;
var header = `GET /hello HTTP/1.1${CRLF}Content-Type: text/plain${CRLF}`;

for (var i = 0; i < fields; i++) {
for (var i = 0; i < len; i++) {
header += `X-Filler${i}: ${Math.random().toString(36).substr(2)}${CRLF}`;
}
header += CRLF;
Expand Down
8 changes: 4 additions & 4 deletions benchmark/http/chunked.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,14 @@
var common = require('../common.js');

var bench = common.createBenchmark(main, {
num: [1, 4, 8, 16],
size: [1, 64, 256],
n: [1, 4, 8, 16],
len: [1, 64, 256],
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why change these?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So test-benchmark-http.js can set the parameters for it (otherwise it will need to add --set num=1 --set size=1...also I think it's better to keep the configuration names consistent)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also if we want to do #12068, doing this to other benchmarks too will make it eaiser..

c: [100]
});

function main(conf) {
const http = require('http');
var chunk = Buffer.alloc(conf.size, '8');
var chunk = Buffer.alloc(conf.len, '8');

var server = http.createServer(function(req, res) {
function send(left) {
Expand All @@ -28,7 +28,7 @@ function main(conf) {
send(left - 1);
}, 0);
}
send(conf.num);
send(conf.n);
});

server.listen(common.PORT, function() {
Expand Down
4 changes: 2 additions & 2 deletions benchmark/http/client-request-body.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@ var http = require('http');
var bench = common.createBenchmark(main, {
dur: [5],
type: ['asc', 'utf', 'buf'],
bytes: [32, 256, 1024],
len: [32, 256, 1024],
method: ['write', 'end']
});

function main(conf) {
var dur = +conf.dur;
var len = +conf.bytes;
var len = +conf.len;

var encoding;
var chunk;
Expand Down
7 changes: 4 additions & 3 deletions benchmark/http/cluster.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,12 @@ if (cluster.isMaster) {
var bench = common.createBenchmark(main, {
// unicode confuses ab on os x.
type: ['bytes', 'buffer'],
length: [4, 1024, 102400],
len: [4, 1024, 102400],
c: [50, 500]
});
} else {
require('./_http_simple.js');
var port = parseInt(process.env.PORT || PORT);
require('../fixtures/simple-http-server.js').listen(port);
}

function main(conf) {
Expand All @@ -26,7 +27,7 @@ function main(conf) {
return;

setTimeout(function() {
var path = '/' + conf.type + '/' + conf.length;
var path = '/' + conf.type + '/' + conf.len;

bench.http({
path: path,
Expand Down
6 changes: 3 additions & 3 deletions benchmark/http/create-clientrequest.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@ var common = require('../common.js');
var ClientRequest = require('http').ClientRequest;

var bench = common.createBenchmark(main, {
pathlen: [1, 8, 16, 32, 64, 128],
len: [1, 8, 16, 32, 64, 128],
n: [1e6]
});

function main(conf) {
var pathlen = +conf.pathlen;
var len = +conf.len;
var n = +conf.n;

var path = '/'.repeat(pathlen);
var path = '/'.repeat(len);
var opts = { path: path, createConnection: function() {} };

bench.start();
Expand Down
4 changes: 2 additions & 2 deletions benchmark/http/end-vs-write-end.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,15 @@ var common = require('../common.js');

var bench = common.createBenchmark(main, {
type: ['asc', 'utf', 'buf'],
kb: [64, 128, 256, 1024],
len: [64 * 1024, 128 * 1024, 256 * 1024, 1024 * 1024],
c: [100],
method: ['write', 'end']
});

function main(conf) {
const http = require('http');
var chunk;
var len = conf.kb * 1024;
var len = conf.len;
switch (conf.type) {
case 'buf':
chunk = Buffer.alloc(len, 'x');
Expand Down
11 changes: 6 additions & 5 deletions benchmark/http/simple.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,18 @@ var PORT = common.PORT;
var bench = common.createBenchmark(main, {
// unicode confuses ab on os x.
type: ['bytes', 'buffer'],
length: [4, 1024, 102400],
len: [4, 1024, 102400],
chunks: [0, 1, 4], // chunks=0 means 'no chunked encoding'.
c: [50, 500],
res: ['normal', 'setHeader', 'setHeaderWH']
});

function main(conf) {
process.env.PORT = PORT;
var server = require('./_http_simple.js');
setTimeout(function() {
var path = '/' + conf.type + '/' + conf.length + '/' + conf.chunks + '/' +
var server = require('../fixtures/simple-http-server.js')
.listen(process.env.PORT || common.PORT)
.on('listening', function() {
var path = '/' + conf.type + '/' + conf.len + '/' + conf.chunks + '/' +
conf.res;

bench.http({
Expand All @@ -24,5 +25,5 @@ function main(conf) {
}, function() {
server.close();
});
}, 2000);
});
}
Loading