crypto,tls: perf improvements for crypto and tls getCiphers
Improve performance of crypto.getCiphers, getHashes, getCurves and tls.getCiphers by consolidating filterDuplicates logic, adding caching of output, and streamlining filterDuplicates implementation. Benchmarks: crypto.getCiphers n=1 v6.2.1 = 2559.3, new = 15890 ...... -83.89% crypto.getCiphers n=5000 v6.2.1 = 3516.3, new = 24203000 ... -99.99% tls.getCiphers n=1 v6.2.1 = 3405.3, new = 14877 ...... -77.11% tls.getCiphers n=5000 v6.2.1 = 6074.4, new = 24202000 ... -99.97% PR-URL: https://github.com/nodejs/node/pull/7225 Reviewed-By: Fedor Indutny <fedor.indutny@gmail.com> Reviewed-By: Brian White <mscdex@mscdex.net>
This commit is contained in:
parent
58a241d537
commit
6be73feaeb
20
benchmark/crypto/get-ciphers.js
Normal file
20
benchmark/crypto/get-ciphers.js
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const common = require('../common.js');
|
||||||
|
|
||||||
|
const bench = common.createBenchmark(main, {
|
||||||
|
n: [1, 5000],
|
||||||
|
v: ['crypto', 'tls']
|
||||||
|
});
|
||||||
|
|
||||||
|
function main(conf) {
|
||||||
|
const n = +conf.n;
|
||||||
|
const v = conf.v;
|
||||||
|
const method = require(v).getCiphers;
|
||||||
|
var i = 0;
|
||||||
|
|
||||||
|
common.v8ForceOptimization(method);
|
||||||
|
bench.start();
|
||||||
|
for (; i < n; i++) method();
|
||||||
|
bench.end(n);
|
||||||
|
}
|
@ -632,41 +632,23 @@ exports.randomBytes = exports.pseudoRandomBytes = randomBytes;
|
|||||||
|
|
||||||
exports.rng = exports.prng = randomBytes;
|
exports.rng = exports.prng = randomBytes;
|
||||||
|
|
||||||
exports.getCiphers = function() {
|
exports.getCiphers = internalUtil.cachedResult(() => {
|
||||||
return filterDuplicates(getCiphers());
|
return internalUtil.filterDuplicateStrings(getCiphers());
|
||||||
};
|
});
|
||||||
|
|
||||||
|
exports.getHashes = internalUtil.cachedResult(() => {
|
||||||
|
return internalUtil.filterDuplicateStrings(getHashes());
|
||||||
|
});
|
||||||
|
|
||||||
exports.getHashes = function() {
|
exports.getCurves = internalUtil.cachedResult(() => {
|
||||||
return filterDuplicates(getHashes());
|
return internalUtil.filterDuplicateStrings(getCurves());
|
||||||
};
|
});
|
||||||
|
|
||||||
|
|
||||||
exports.getCurves = function() {
|
|
||||||
return filterDuplicates(getCurves());
|
|
||||||
};
|
|
||||||
|
|
||||||
Object.defineProperty(exports, 'fips', {
|
Object.defineProperty(exports, 'fips', {
|
||||||
get: getFipsCrypto,
|
get: getFipsCrypto,
|
||||||
set: setFipsCrypto
|
set: setFipsCrypto
|
||||||
});
|
});
|
||||||
|
|
||||||
function filterDuplicates(names) {
|
|
||||||
// Drop all-caps names in favor of their lowercase aliases,
|
|
||||||
// for example, 'sha1' instead of 'SHA1'.
|
|
||||||
var ctx = {};
|
|
||||||
names.forEach(function(name) {
|
|
||||||
var key = name;
|
|
||||||
if (/^[0-9A-Z\-]+$/.test(key)) key = key.toLowerCase();
|
|
||||||
if (!ctx.hasOwnProperty(key) || ctx[key] < name)
|
|
||||||
ctx[key] = name;
|
|
||||||
});
|
|
||||||
|
|
||||||
return Object.getOwnPropertyNames(ctx).map(function(key) {
|
|
||||||
return ctx[key];
|
|
||||||
}).sort();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Legacy API
|
// Legacy API
|
||||||
Object.defineProperty(exports, 'createCredentials', {
|
Object.defineProperty(exports, 'createCredentials', {
|
||||||
configurable: true,
|
configurable: true,
|
||||||
|
@ -121,3 +121,34 @@ exports.normalizeEncoding = function normalizeEncoding(enc) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Filters duplicate strings. Used to support functions in crypto and tls
|
||||||
|
// modules. Implemented specifically to maintain existing behaviors in each.
|
||||||
|
exports.filterDuplicateStrings = function filterDuplicateStrings(items, low) {
|
||||||
|
if (!Array.isArray(items))
|
||||||
|
return [];
|
||||||
|
const len = items.length;
|
||||||
|
if (len <= 1)
|
||||||
|
return items;
|
||||||
|
const map = new Map();
|
||||||
|
for (var i = 0; i < len; i++) {
|
||||||
|
const item = items[i];
|
||||||
|
const key = item.toLowerCase();
|
||||||
|
if (low) {
|
||||||
|
map.set(key, key);
|
||||||
|
} else {
|
||||||
|
if (!map.has(key) || map.get(key) <= item)
|
||||||
|
map.set(key, item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Array.from(map.values()).sort();
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.cachedResult = function cachedResult(fn) {
|
||||||
|
var result;
|
||||||
|
return () => {
|
||||||
|
if (result === undefined)
|
||||||
|
result = fn();
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
16
lib/tls.js
16
lib/tls.js
@ -1,6 +1,7 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
require('internal/util').assertCrypto(exports);
|
const internalUtil = require('internal/util');
|
||||||
|
internalUtil.assertCrypto(exports);
|
||||||
|
|
||||||
const net = require('net');
|
const net = require('net');
|
||||||
const url = require('url');
|
const url = require('url');
|
||||||
@ -21,16 +22,9 @@ exports.DEFAULT_CIPHERS =
|
|||||||
|
|
||||||
exports.DEFAULT_ECDH_CURVE = 'prime256v1';
|
exports.DEFAULT_ECDH_CURVE = 'prime256v1';
|
||||||
|
|
||||||
exports.getCiphers = function() {
|
exports.getCiphers = internalUtil.cachedResult(() => {
|
||||||
const names = binding.getSSLCiphers();
|
return internalUtil.filterDuplicateStrings(binding.getSSLCiphers(), true);
|
||||||
// Drop all-caps names in favor of their lowercase aliases,
|
});
|
||||||
var ctx = {};
|
|
||||||
names.forEach(function(name) {
|
|
||||||
if (/^[0-9A-Z\-]+$/.test(name)) name = name.toLowerCase();
|
|
||||||
ctx[name] = true;
|
|
||||||
});
|
|
||||||
return Object.getOwnPropertyNames(ctx).sort();
|
|
||||||
};
|
|
||||||
|
|
||||||
// Convert protocols array into valid OpenSSL protocols list
|
// Convert protocols array into valid OpenSSL protocols list
|
||||||
// ("\x06spdy/2\x08http/1.1\x08http/1.0")
|
// ("\x06spdy/2\x08http/1.1\x08http/1.0")
|
||||||
|
Loading…
x
Reference in New Issue
Block a user