http: speed up checkIsHttpToken
The Regex implementation is not faster than ascii code compare. the field name is shorter, the speed is faster. benchmark result here: https://bitbucket.org/snippets/JacksonTian/Rnbad/benchmark-result PR-URL: https://github.com/nodejs/node/pull/4790 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Brian White <mscdex@mscdex.net>
This commit is contained in:
parent
293fd04535
commit
089c6a4fba
52
benchmark/http/check_is_http_token.js
Normal file
52
benchmark/http/check_is_http_token.js
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const common = require('../common.js');
|
||||||
|
const _checkIsHttpToken = require('_http_common')._checkIsHttpToken;
|
||||||
|
|
||||||
|
const bench = common.createBenchmark(main, {
|
||||||
|
key: [
|
||||||
|
'TCN',
|
||||||
|
'ETag',
|
||||||
|
'date',
|
||||||
|
'Vary',
|
||||||
|
'server',
|
||||||
|
'Server',
|
||||||
|
'status',
|
||||||
|
'version',
|
||||||
|
'Expires',
|
||||||
|
'alt-svc',
|
||||||
|
'location',
|
||||||
|
'Connection',
|
||||||
|
'Keep-Alive',
|
||||||
|
'content-type',
|
||||||
|
'Content-Type',
|
||||||
|
'Cache-Control',
|
||||||
|
'Last-Modified',
|
||||||
|
'Accept-Ranges',
|
||||||
|
'content-length',
|
||||||
|
'x-frame-options',
|
||||||
|
'x-xss-protection',
|
||||||
|
'Content-Encoding',
|
||||||
|
'Content-Location',
|
||||||
|
'Transfer-Encoding',
|
||||||
|
'alternate-protocol',
|
||||||
|
':', // invalid input
|
||||||
|
'@@',
|
||||||
|
'中文呢', // unicode
|
||||||
|
'((((())))', // invalid
|
||||||
|
':alternate-protocol', // fast bailout
|
||||||
|
'alternate-protocol:' // slow bailout
|
||||||
|
],
|
||||||
|
n: [1e6],
|
||||||
|
});
|
||||||
|
|
||||||
|
function main(conf) {
|
||||||
|
var n = +conf.n;
|
||||||
|
var key = conf.key;
|
||||||
|
|
||||||
|
bench.start();
|
||||||
|
for (var i = 0; i < n; i++) {
|
||||||
|
_checkIsHttpToken(key);
|
||||||
|
}
|
||||||
|
bench.end(n);
|
||||||
|
}
|
@ -225,10 +225,56 @@ exports.httpSocketSetup = httpSocketSetup;
|
|||||||
/**
|
/**
|
||||||
* Verifies that the given val is a valid HTTP token
|
* Verifies that the given val is a valid HTTP token
|
||||||
* per the rules defined in RFC 7230
|
* per the rules defined in RFC 7230
|
||||||
|
* See https://tools.ietf.org/html/rfc7230#section-3.2.6
|
||||||
|
*
|
||||||
|
* This implementation of checkIsHttpToken() loops over the string instead of
|
||||||
|
* using a regular expression since the former is up to 180% faster with v8 4.9
|
||||||
|
* depending on the string length (the shorter the string, the larger the
|
||||||
|
* performance difference)
|
||||||
**/
|
**/
|
||||||
const token = /^[a-zA-Z0-9_!#$%&'*+.^`|~-]+$/;
|
|
||||||
function checkIsHttpToken(val) {
|
function checkIsHttpToken(val) {
|
||||||
return typeof val === 'string' && token.test(val);
|
if (typeof val !== 'string' || val.length === 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
for (var i = 0, len = val.length; i < len; i++) {
|
||||||
|
var ch = val.charCodeAt(i);
|
||||||
|
|
||||||
|
if (ch >= 65 && ch <= 90) // A-Z
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (ch >= 97 && ch <= 122) // a-z
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// ^ => 94
|
||||||
|
// _ => 95
|
||||||
|
// ` => 96
|
||||||
|
// | => 124
|
||||||
|
// ~ => 126
|
||||||
|
if (ch === 94 || ch === 95 || ch === 96 || ch === 124 || ch === 126)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (ch >= 48 && ch <= 57) // 0-9
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// ! => 33
|
||||||
|
// # => 35
|
||||||
|
// $ => 36
|
||||||
|
// % => 37
|
||||||
|
// & => 38
|
||||||
|
// ' => 39
|
||||||
|
// * => 42
|
||||||
|
// + => 43
|
||||||
|
// - => 45
|
||||||
|
// . => 46
|
||||||
|
if (ch >= 33 && ch <= 46) {
|
||||||
|
if (ch === 34 || ch === 40 || ch === 41 || ch === 44)
|
||||||
|
return false;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
exports._checkIsHttpToken = checkIsHttpToken;
|
exports._checkIsHttpToken = checkIsHttpToken;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user