mirror of
https://github.com/mariadb-corporation/mariadb-connector-nodejs.git
synced 2025-08-06 10:17:04 +00:00
396 lines
11 KiB
JavaScript
396 lines
11 KiB
JavaScript
"use strict";
|
|
|
|
const Benchmark = require("benchmark");
|
|
const conf = require("../test/conf");
|
|
|
|
const colors = require("colors");
|
|
const mariadb = require("../promise");
|
|
const callbackMariadb = require("../callback");
|
|
|
|
let promiseMariasql, mariasql, promiseMysql, mysql, promiseMysql2, mysql2;
|
|
|
|
try {
|
|
promiseMysql = require("promise-mysql");
|
|
} catch (err) {}
|
|
|
|
try {
|
|
promiseMysql2 = require("mysql2/promise");
|
|
} catch (err) {}
|
|
|
|
try {
|
|
promiseMariasql = require("mariasql-promise");
|
|
} catch (err) {}
|
|
|
|
try {
|
|
mysql = require("mysql");
|
|
} catch (err) {}
|
|
|
|
try {
|
|
mysql2 = require("mysql2");
|
|
} catch (err) {}
|
|
|
|
try {
|
|
mariasql = require("mariasql");
|
|
} catch (err) {}
|
|
|
|
function Bench() {
|
|
this.dbReady = 0;
|
|
this.reportData = {};
|
|
|
|
this.driverLen = 2;
|
|
|
|
this.ready = 0;
|
|
this.suiteReady = function() {
|
|
this.ready++;
|
|
if (this.ready === 2) {
|
|
this.suite.run();
|
|
}
|
|
};
|
|
|
|
const dbReady = function(name, driverLen) {
|
|
bench.dbReady++;
|
|
console.log("driver for " + name + " connected (" + bench.dbReady + "/" + driverLen + ")");
|
|
if (bench.dbReady === driverLen) {
|
|
bench.suiteReady();
|
|
}
|
|
};
|
|
|
|
const config = conf.baseConfig;
|
|
config.charsetNumber = 224;
|
|
config.trace = false;
|
|
// config.debug = true;
|
|
// if (!mariasql && process.platform === "win32") {
|
|
// config.socketPath = "\\\\.\\pipe\\MySQL";
|
|
// }
|
|
|
|
console.log(config);
|
|
|
|
this.CONN = {};
|
|
const bench = this;
|
|
const connList = this.CONN;
|
|
|
|
if (promiseMysql) {
|
|
this.driverLen++;
|
|
connList["PROMISE_MYSQL"] = { desc: "promise-mysql", promise: true };
|
|
promiseMysql
|
|
.createConnection(config)
|
|
.then(conn => {
|
|
connList["PROMISE_MYSQL"].drv = conn;
|
|
dbReady("promise-mysql", this.driverLen);
|
|
})
|
|
.catch(err => {
|
|
throw err;
|
|
});
|
|
}
|
|
|
|
if (mysql) {
|
|
this.driverLen++;
|
|
connList["MYSQL"] = { desc: "mysql", promise: false };
|
|
const conn = mysql.createConnection(config);
|
|
conn.connect(err => {
|
|
connList["MYSQL"].drv = conn;
|
|
conn.on("error", err => console.log("driver mysql error :" + err));
|
|
dbReady("mysql", this.driverLen);
|
|
});
|
|
}
|
|
|
|
if (mysql2) {
|
|
this.driverLen++;
|
|
connList["MYSQL2"] = { desc: "mysql2", promise: false };
|
|
const conn = mysql2.createConnection(config);
|
|
conn.connect(() => {
|
|
connList["MYSQL2"].drv = conn;
|
|
conn.on("error", err => console.log("driver mysql2 error :" + err));
|
|
dbReady("mysql2", this.driverLen);
|
|
});
|
|
}
|
|
|
|
if (promiseMysql2) {
|
|
this.driverLen++;
|
|
connList["PROMISE_MYSQL2"] = { desc: "promise mysql2", promise: true };
|
|
promiseMysql2
|
|
.createConnection(config)
|
|
.then(conn => {
|
|
connList["PROMISE_MYSQL2"].drv = conn;
|
|
conn.on("error", err => console.log("driver mysql2 promise error :" + err));
|
|
dbReady("promise mysql2", this.driverLen);
|
|
})
|
|
.catch(err => {
|
|
throw err;
|
|
});
|
|
}
|
|
|
|
const mariaConn = callbackMariadb.createConnection(config);
|
|
connList["MARIADB"] = { desc: "mariadb", promise: true };
|
|
mariaConn.connect(() => {
|
|
connList["MARIADB"].drv = mariaConn;
|
|
mariaConn.on("error", err => console.log("driver mariadb error :" + err));
|
|
dbReady("mariadb", this.driverLen);
|
|
});
|
|
|
|
connList["PROMISE_MARIADB"] = { desc: "promise mariadb", promise: false };
|
|
mariadb
|
|
.createConnection(config)
|
|
.then(conn => {
|
|
connList["PROMISE_MARIADB"].drv = conn;
|
|
conn.on("error", err => console.log("driver mariadb promise error :" + err));
|
|
dbReady("promise-mariadb", this.driverLen);
|
|
})
|
|
.catch(err => {
|
|
throw err;
|
|
});
|
|
|
|
const configC = Object.assign({}, config);
|
|
configC.charset = "utf8mb4";
|
|
configC.db = config.database;
|
|
configC.metadata = true;
|
|
if (config.socketPath != null) {
|
|
configC.unixSocket = config.socketPath;
|
|
configC.protocol = "socket";
|
|
}
|
|
|
|
if (promiseMariasql) {
|
|
this.driverLen++;
|
|
connList["PROMISE_MARIASQL"] = { desc: "promise mariasql", promise: false };
|
|
promiseMariasql
|
|
.createConnection(config)
|
|
.then(conn => {
|
|
connList["PROMISE_MARIASQL"].drv = conn;
|
|
dbReady("promise-mariasql", this.driverLen);
|
|
})
|
|
.catch(err => {
|
|
throw err;
|
|
});
|
|
}
|
|
|
|
if (mariasql) {
|
|
this.driverLen++;
|
|
connList["MARIASQL"] = { desc: "mariasql", drv: conn, promise: true };
|
|
const conn = mariasql.createConnection(config);
|
|
conn.connect(err => {
|
|
connList["MARIASQL"].drv = conn;
|
|
dbReady("mariasql", this.driverLen);
|
|
});
|
|
}
|
|
|
|
this.initFcts = [];
|
|
//200 is a minimum to have benchmark average variation of 1%
|
|
this.minSamples = 200;
|
|
|
|
this.suite = new Benchmark.Suite("foo", {
|
|
// called when the suite starts running
|
|
onStart: function() {
|
|
console.log("start : init test : " + bench.initFcts.length);
|
|
for (let i = 0; i < bench.initFcts.length; i++) {
|
|
console.log("initializing test data " + (i + 1) + "/" + bench.initFcts.length);
|
|
if (bench.initFcts[i]) {
|
|
bench.initFcts[i].call(this, bench.CONN.MARIADB.drv);
|
|
}
|
|
}
|
|
console.log("initializing test data done");
|
|
},
|
|
|
|
// called between running benchmarks
|
|
onCycle: function(event) {
|
|
pingAll(connList);
|
|
//to avoid mysql2 taking all the server memory
|
|
if (promiseMysql2 && promiseMysql2.clearParserCache) promiseMysql2.clearParserCache();
|
|
if (mysql2 && mysql2.clearParserCache) mysql2.clearParserCache();
|
|
console.log(event.target.toString());
|
|
const drvType = event.target.options.drvType;
|
|
const benchTitle =
|
|
event.target.options.benchTitle + " ( sql: " + event.target.options.displaySql + " )";
|
|
const iteration = 1 / event.target.times.period;
|
|
const variation = event.target.stats.rme;
|
|
|
|
if (!bench.reportData[benchTitle]) {
|
|
bench.reportData[benchTitle] = [];
|
|
}
|
|
if (drvType !== "warmup") {
|
|
bench.reportData[benchTitle].push({
|
|
drvType: drvType,
|
|
iteration: iteration,
|
|
variation: variation
|
|
});
|
|
}
|
|
},
|
|
// called when the suite completes running
|
|
onComplete: function() {
|
|
bench.end(bench);
|
|
}
|
|
});
|
|
}
|
|
|
|
Bench.prototype.end = function(bench) {
|
|
console.log("ending connectors");
|
|
this.endConnection(this.CONN.MARIADB);
|
|
this.endConnection(this.CONN.PROMISE_MARIADB);
|
|
if (mysql) this.endConnection(this.CONN.MYSQL);
|
|
if (mysql2) this.endConnection(this.CONN.MYSQL2);
|
|
if (mariasql) this.endConnection(this.CONN.MARIASQL);
|
|
|
|
if (promiseMysql) this.endConnection(this.CONN.PROMISE_MYSQL);
|
|
if (promiseMysql2) this.endConnection(this.CONN.PROMISE_MYSQL2);
|
|
if (promiseMariasql) this.endConnection(this.CONN.PROMISE_MARIASQL);
|
|
bench.displayReport();
|
|
};
|
|
|
|
Bench.prototype.endConnection = function(conn) {
|
|
try {
|
|
//using destroy, because MySQL driver fail when using end() for windows named pipe
|
|
conn.drv.destroy();
|
|
} catch (err) {
|
|
console.log("ending error for connection '" + conn.desc + "'");
|
|
console.log(err);
|
|
}
|
|
};
|
|
|
|
Bench.prototype.displayReport = function() {
|
|
const simpleFormat = new Intl.NumberFormat("en-EN", {
|
|
maximumFractionDigits: 1
|
|
});
|
|
const simpleFormatPerc = new Intl.NumberFormat("en-EN", {
|
|
style: "percent",
|
|
maximumFractionDigits: 1
|
|
});
|
|
|
|
console.log("");
|
|
console.log("");
|
|
console.log("--- BENCHMARK RESULTS ---".yellow);
|
|
console.log(
|
|
"/* travis bench are not to take as is, because VM might run some other testing script that can change results */"
|
|
.gray
|
|
);
|
|
|
|
const keys = Object.keys(this.reportData);
|
|
for (let i = 0; i < keys.length; i++) {
|
|
let base = 0;
|
|
let best = 0;
|
|
let data = this.reportData[keys[i]];
|
|
|
|
for (let j = 0; j < data.length; j++) {
|
|
let o = data[j];
|
|
if (o.drvType === "mysql" || o.drvType === "promise-mysql") {
|
|
base = o.iteration;
|
|
}
|
|
if (o.iteration > best) {
|
|
best = o.iteration;
|
|
}
|
|
}
|
|
|
|
//display results
|
|
console.log("");
|
|
console.log("bench : " + keys[i]);
|
|
for (let j = 0; j < data.length; j++) {
|
|
let o = data[j];
|
|
const val = (100 * (o.iteration - base)) / base;
|
|
const perc = simpleFormat.format(val);
|
|
const tt =
|
|
" " +
|
|
this.fill(o.drvType, 10) +
|
|
" : " +
|
|
this.fill(simpleFormat.format(o.iteration), 8, false) +
|
|
" ops/s " +
|
|
//'±' +this.fill(simpleFormat.format(o.variation), 6, false) + '%' +
|
|
(o.iteration === base
|
|
? ""
|
|
: " ( " + this.fill((val > 0 ? "+" : "") + perc, 6, false) + "% )");
|
|
if (o.drvType.includes("mariadb")) {
|
|
if (o.iteration < best) {
|
|
console.log(tt.red);
|
|
} else {
|
|
console.log(tt.green);
|
|
}
|
|
} else {
|
|
console.log(tt);
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
Bench.prototype.fill = function(val, length, right) {
|
|
if (right) {
|
|
while (val.length < length) {
|
|
val += " ";
|
|
}
|
|
} else {
|
|
while (val.length < length) {
|
|
val = " " + val;
|
|
}
|
|
}
|
|
return val;
|
|
};
|
|
|
|
Bench.prototype.add = function(title, displaySql, fct, onComplete, isPromise, conn) {
|
|
const self = this;
|
|
const addTest = getAddTest(self, this.suite, fct, this.minSamples, title, displaySql, onComplete);
|
|
|
|
if (conn) {
|
|
addTest(conn, conn.desc);
|
|
} else {
|
|
if (isPromise) {
|
|
addTest(self.CONN.PROMISE_MARIADB, "warmup");
|
|
} else {
|
|
addTest(self.CONN.MARIADB, "warmup");
|
|
}
|
|
|
|
if (!isPromise && mysql) {
|
|
addTest(self.CONN.MYSQL, self.CONN.MYSQL.desc);
|
|
}
|
|
|
|
if (isPromise && promiseMysql) {
|
|
addTest(self.CONN.PROMISE_MYSQL, self.CONN.PROMISE_MYSQL.desc);
|
|
}
|
|
|
|
if (!isPromise && mysql2) {
|
|
addTest(self.CONN.MYSQL2, self.CONN.MYSQL2.desc);
|
|
}
|
|
|
|
if (isPromise && promiseMysql2) {
|
|
addTest(self.CONN.PROMISE_MYSQL2, self.CONN.PROMISE_MYSQL2.desc);
|
|
}
|
|
|
|
if (isPromise) {
|
|
addTest(self.CONN.PROMISE_MARIADB, self.CONN.PROMISE_MARIADB.desc);
|
|
} else {
|
|
addTest(self.CONN.MARIADB, self.CONN.MARIADB.desc);
|
|
}
|
|
|
|
if (isPromise && promiseMariasql) {
|
|
addTest(self.CONN.PROMISE_MARIASQL, self.CONN.PROMISE_MARIASQL.desc);
|
|
}
|
|
|
|
if (!isPromise && mariasql) {
|
|
addTest(self.CONN.MARIASQL, self.CONN.MARIASQL.desc);
|
|
}
|
|
}
|
|
};
|
|
|
|
const getAddTest = function(self, suite, fct, minSamples, title, displaySql, onComplete) {
|
|
return function(conn, name) {
|
|
suite.add({
|
|
name: title + " - " + name,
|
|
fn: function(deferred) {
|
|
fct.call(self, conn.drv, deferred);
|
|
},
|
|
onComplete: () => {
|
|
if (onComplete) onComplete.call(self, conn.drv);
|
|
},
|
|
minSamples: minSamples,
|
|
defer: true,
|
|
drvType: name,
|
|
benchTitle: title,
|
|
displaySql: displaySql
|
|
});
|
|
};
|
|
};
|
|
|
|
const pingAll = function(conns) {
|
|
let keys = Object.keys(conns);
|
|
for (let k = 0; k < keys.length; ++k) {
|
|
conns[keys[k]].drv.ping();
|
|
}
|
|
};
|
|
|
|
module.exports = Bench;
|