Skip to content

Commit 2c7804a

Browse files
jasnellFishrock123
authored andcommitted
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: #7225 Reviewed-By: Fedor Indutny <fedor.indutny@gmail.com> Reviewed-By: Brian White <mscdex@mscdex.net> Conflicts: lib/internal/util.js
1 parent 0593351 commit 2c7804a

4 files changed

Lines changed: 65 additions & 38 deletions

File tree

‎benchmark/crypto/get-ciphers.js‎

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
'use strict';
2+
3+
constcommon=require('../common.js');
4+
5+
constbench=common.createBenchmark(main,{
6+
n: [1,5000],
7+
v: ['crypto','tls']
8+
});
9+
10+
functionmain(conf){
11+
constn=+conf.n;
12+
constv=conf.v;
13+
constmethod=require(v).getCiphers;
14+
vari=0;
15+
16+
common.v8ForceOptimization(method);
17+
bench.start();
18+
for(;i<n;i++)method();
19+
bench.end(n);
20+
}

‎lib/crypto.js‎

Lines changed: 9 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -632,41 +632,23 @@ exports.randomBytes = exports.pseudoRandomBytes = randomBytes;
632632

633633
exports.rng=exports.prng=randomBytes;
634634

635-
exports.getCiphers=function(){
636-
returnfilterDuplicates(getCiphers());
637-
};
638-
639-
640-
exports.getHashes=function(){
641-
returnfilterDuplicates(getHashes());
642-
};
635+
exports.getCiphers=internalUtil.cachedResult(()=>{
636+
returninternalUtil.filterDuplicateStrings(getCiphers());
637+
});
643638

639+
exports.getHashes=internalUtil.cachedResult(()=>{
640+
returninternalUtil.filterDuplicateStrings(getHashes());
641+
});
644642

645-
exports.getCurves=function(){
646-
returnfilterDuplicates(getCurves());
647-
};
643+
exports.getCurves=internalUtil.cachedResult(()=>{
644+
returninternalUtil.filterDuplicateStrings(getCurves());
645+
});
648646

649647
Object.defineProperty(exports,'fips',{
650648
get: getFipsCrypto,
651649
set: setFipsCrypto
652650
});
653651

654-
functionfilterDuplicates(names){
655-
// Drop all-caps names in favor of their lowercase aliases,
656-
// for example, 'sha1' instead of 'SHA1'.
657-
varctx={};
658-
names.forEach(function(name){
659-
varkey=name;
660-
if(/^[0-9A-Z\-]+$/.test(key))key=key.toLowerCase();
661-
if(!ctx.hasOwnProperty(key)||ctx[key]<name)
662-
ctx[key]=name;
663-
});
664-
665-
returnObject.getOwnPropertyNames(ctx).map(function(key){
666-
returnctx[key];
667-
}).sort();
668-
}
669-
670652
// Legacy API
671653
Object.defineProperty(exports,'createCredentials',{
672654
configurable: true,

‎lib/internal/util.js‎

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,3 +89,34 @@ exports.assertCrypto = function(exports) {
8989
if(noCrypto)
9090
thrownewError('Node.js is not compiled with openssl crypto support');
9191
};
92+
93+
// Filters duplicate strings. Used to support functions in crypto and tls
94+
// modules. Implemented specifically to maintain existing behaviors in each.
95+
exports.filterDuplicateStrings=functionfilterDuplicateStrings(items,low){
96+
if(!Array.isArray(items))
97+
return[];
98+
constlen=items.length;
99+
if(len<=1)
100+
returnitems;
101+
constmap=newMap();
102+
for(vari=0;i<len;i++){
103+
constitem=items[i];
104+
constkey=item.toLowerCase();
105+
if(low){
106+
map.set(key,key);
107+
}else{
108+
if(!map.has(key)||map.get(key)<=item)
109+
map.set(key,item);
110+
}
111+
}
112+
returnArray.from(map.values()).sort();
113+
};
114+
115+
exports.cachedResult=functioncachedResult(fn){
116+
varresult;
117+
return()=>{
118+
if(result===undefined)
119+
result=fn();
120+
returnresult;
121+
};
122+
};

‎lib/tls.js‎

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
'use strict';
22

3-
require('internal/util').assertCrypto(exports);
3+
constinternalUtil=require('internal/util');
4+
internalUtil.assertCrypto(exports);
45

56
constnet=require('net');
67
consturl=require('url');
@@ -21,16 +22,9 @@ exports.DEFAULT_CIPHERS =
2122

2223
exports.DEFAULT_ECDH_CURVE='prime256v1';
2324

24-
exports.getCiphers=function(){
25-
constnames=binding.getSSLCiphers();
26-
// Drop all-caps names in favor of their lowercase aliases,
27-
varctx={};
28-
names.forEach(function(name){
29-
if(/^[0-9A-Z\-]+$/.test(name))name=name.toLowerCase();
30-
ctx[name]=true;
31-
});
32-
returnObject.getOwnPropertyNames(ctx).sort();
33-
};
25+
exports.getCiphers=internalUtil.cachedResult(()=>{
26+
returninternalUtil.filterDuplicateStrings(binding.getSSLCiphers(),true);
27+
});
3428

3529
// Convert protocols array into valid OpenSSL protocols list
3630
// ("\x06spdy/2\x08http/1.1\x08http/1.0")

0 commit comments

Comments
 (0)