diff options
author | Jackson Tian <shyvo1987@gmail.com> | 2016-01-21 15:53:20 +0800 |
---|---|---|
committer | James M Snell <jasnell@gmail.com> | 2016-03-27 13:58:26 -0700 |
commit | 089c6a4fbaa4f0c737ad1ca09b8f823459983d3a (patch) | |
tree | 96cf62dd794fe24f214c0d4d84de1e7eb7e268b3 /lib | |
parent | 293fd0453591ef0d87437a265ff515916d35d715 (diff) | |
download | android-node-v8-089c6a4fbaa4f0c737ad1ca09b8f823459983d3a.tar.gz android-node-v8-089c6a4fbaa4f0c737ad1ca09b8f823459983d3a.tar.bz2 android-node-v8-089c6a4fbaa4f0c737ad1ca09b8f823459983d3a.zip |
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>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/_http_common.js | 50 |
1 files changed, 48 insertions, 2 deletions
diff --git a/lib/_http_common.js b/lib/_http_common.js index 328b6eea8a..08f93d8c4d 100644 --- a/lib/_http_common.js +++ b/lib/_http_common.js @@ -225,10 +225,56 @@ exports.httpSocketSetup = httpSocketSetup; /** * Verifies that the given val is a valid HTTP token * 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) { - 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; |