-
Notifications
You must be signed in to change notification settings - Fork 29.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
http: speed up checkIsHttpToken #4790
Conversation
Can you add a comment above // 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.7
// depending on the string length (the shorter the string, the larger the
// performance difference) |
if (typeof val !== 'string') | ||
return false; | ||
|
||
for (var i = 0, len = val.length; i < len; i++) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
const len = val.length;
for (let i = 0; i < len; i++) {
Not sure if it matters or improves anything.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It means the same, so shouldn't matter.
LGTM |
26fd567
to
6f7e790
Compare
@mscdex ... can I ask you to take another look? |
LGTM if CI is still ok with it: https://ci.nodejs.org/job/node-test-pull-request/1356/ |
@JacksonTian Most probably things didn't change, but just in case — could you rebase against current master and re-run the benchmarks, please? v8 4.8 has landed to |
* 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.7 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This comment probably should also be updated to reflect the situation on v8 4.8 (that most likely didn't change, but still it would be better to re-check that).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well if it performs the same, the comment is fine as-is.
@JacksonTian It seems that the benchmark is currently not checking strings (short and long) that are not valid tokens. Adding those would complete the picture. |
Thanks, @ronkorving , should check the length of string. |
@ronkorving Note that strings that are not valid tokens should be never hit in valid code, and definitely they wouldn't be in the hot code path. |
@ChALkeR I'm aware that they would not be in the hot code path, but it can happen in valid code, can't it? (I can send whatever I want to your server). |
Just a quick note... This function is not called when an http message is received and parsed. This is only and called when a header is set, and yes, it's whole point is to make sure the input is valid. Benchmarking with invalid input makes sense. |
6f7e790
to
8cfc0f8
Compare
Updated the benchmarks: $ ./node benchmark/compare.js ./node ~/.tnvm/versions/node/v5.5.0/bin/node -- http check_is_http_token.js
running ./node
http/check_is_http_token.js
running /Users/jacksontian/.tnvm/versions/node/v5.5.0/bin/node
http/check_is_http_token.js
http/check_is_http_token.js key=TCN n=1000000: ./node: 51572000 /Users/jacksontian/.tnvm/versions/node/v5.5.0/bin/node: 15310000 ................. 236.86%
http/check_is_http_token.js key=ETag n=1000000: ./node: 48290000 /Users/jacksontian/.tnvm/versions/node/v5.5.0/bin/node: 17196000 ................ 180.82%
http/check_is_http_token.js key=date n=1000000: ./node: 36327000 /Users/jacksontian/.tnvm/versions/node/v5.5.0/bin/node: 18460000 ................. 96.79%
http/check_is_http_token.js key=Vary n=1000000: ./node: 41768000 /Users/jacksontian/.tnvm/versions/node/v5.5.0/bin/node: 15744000 ................ 165.30%
http/check_is_http_token.js key=server n=1000000: ./node: 26680000 /Users/jacksontian/.tnvm/versions/node/v5.5.0/bin/node: 15540000 ............... 71.68%
http/check_is_http_token.js key=Server n=1000000: ./node: 30184000 /Users/jacksontian/.tnvm/versions/node/v5.5.0/bin/node: 12586000 .............. 139.83%
http/check_is_http_token.js key=status n=1000000: ./node: 31065000 /Users/jacksontian/.tnvm/versions/node/v5.5.0/bin/node: 14091000 .............. 120.46%
http/check_is_http_token.js key=version n=1000000: ./node: 27162000 /Users/jacksontian/.tnvm/versions/node/v5.5.0/bin/node: 14666000 .............. 85.21%
http/check_is_http_token.js key=Expires n=1000000: ./node: 23853000 /Users/jacksontian/.tnvm/versions/node/v5.5.0/bin/node: 13385000 .............. 78.21%
http/check_is_http_token.js key=alt-svc n=1000000: ./node: 27987000 /Users/jacksontian/.tnvm/versions/node/v5.5.0/bin/node: 12539000 ............. 123.20%
http/check_is_http_token.js key=location n=1000000: ./node: 21943000 /Users/jacksontian/.tnvm/versions/node/v5.5.0/bin/node: 13265000 ............. 65.42%
http/check_is_http_token.js key=Connection n=1000000: ./node: 19229000 /Users/jacksontian/.tnvm/versions/node/v5.5.0/bin/node: 12365000 ........... 55.51%
http/check_is_http_token.js key=Keep-Alive n=1000000: ./node: 17815000 /Users/jacksontian/.tnvm/versions/node/v5.5.0/bin/node: 13648000 ........... 30.54%
http/check_is_http_token.js key=content-type n=1000000: ./node: 16488000 /Users/jacksontian/.tnvm/versions/node/v5.5.0/bin/node: 13965000 ......... 18.06%
http/check_is_http_token.js key=Content-Type n=1000000: ./node: 17237000 /Users/jacksontian/.tnvm/versions/node/v5.5.0/bin/node: 12495000 ......... 37.95%
http/check_is_http_token.js key=Cache-Control n=1000000: ./node: 14031000 /Users/jacksontian/.tnvm/versions/node/v5.5.0/bin/node: 13030000 ......... 7.69%
http/check_is_http_token.js key=Last-Modified n=1000000: ./node: 14797000 /Users/jacksontian/.tnvm/versions/node/v5.5.0/bin/node: 9009100 ......... 64.25%
http/check_is_http_token.js key=Accept-Ranges n=1000000: ./node: 13960000 /Users/jacksontian/.tnvm/versions/node/v5.5.0/bin/node: 11130000 ........ 25.43%
http/check_is_http_token.js key=content-length n=1000000: ./node: 13729000 /Users/jacksontian/.tnvm/versions/node/v5.5.0/bin/node: 11711000 ....... 17.23%
http/check_is_http_token.js key=x-frame-options n=1000000: ./node: 11441000 /Users/jacksontian/.tnvm/versions/node/v5.5.0/bin/node: 10915000 ....... 4.82%
http/check_is_http_token.js key=x-xss-protection n=1000000: ./node: 11358000 /Users/jacksontian/.tnvm/versions/node/v5.5.0/bin/node: 11408000 ..... -0.44%
http/check_is_http_token.js key=Content-Encoding n=1000000: ./node: 13669000 /Users/jacksontian/.tnvm/versions/node/v5.5.0/bin/node: 4164100 ..... 228.25%
http/check_is_http_token.js key=Content-Location n=1000000: ./node: 12569000 /Users/jacksontian/.tnvm/versions/node/v5.5.0/bin/node: 11012000 ..... 14.14%
http/check_is_http_token.js key=Transfer-Encoding n=1000000: ./node: 12057000 /Users/jacksontian/.tnvm/versions/node/v5.5.0/bin/node: 11340000 ..... 6.33%
http/check_is_http_token.js key=alternate-protocol n=1000000: ./node: 9157300 /Users/jacksontian/.tnvm/versions/node/v5.5.0/bin/node: 10027000 .... -8.67%
http/check_is_http_token.js key=: n=1000000: ./node: 58233000 /Users/jacksontian/.tnvm/versions/node/v5.5.0/bin/node: 22897000 ................... 154.33%
http/check_is_http_token.js key=@@ n=1000000: ./node: 60918000 /Users/jacksontian/.tnvm/versions/node/v5.5.0/bin/node: 23144000 .................. 163.21%
http/check_is_http_token.js key=中文呢 n=1000000: ./node: 56176000 /Users/jacksontian/.tnvm/versions/node/v5.5.0/bin/node: 22926000 ................. 145.03%
http/check_is_http_token.js key=((((()))) n=1000000: ./node: 49334000 /Users/jacksontian/.tnvm/versions/node/v5.5.0/bin/node: 20424000 ........... 141.55%
http/check_is_http_token.js key=:alternate-protocol n=1000000: ./node: 62579000 /Users/jacksontian/.tnvm/versions/node/v5.5.0/bin/node: 21284000 . 194.02%
http/check_is_http_token.js key=alternate-protocol: n=1000000: ./node: 10406000 /Users/jacksontian/.tnvm/versions/node/v5.5.0/bin/node: 8494400 ... 22.51% |
@jasnell thanks for the feedback on that |
LGTM... one last CI run just to be safe: https://ci.nodejs.org/job/node-test-pull-request/1401/ |
Looks like this one slipped by... old CI run is no longer available. New CI here: https://ci.nodejs.org/job/node-test-pull-request/2007/ |
Looks like there are some linting issues: https://ci.nodejs.org/job/node-test-linter/1756/console |
Sigh.. scratch that on the linting issue. That was my bad. New CI: https://ci.nodejs.org/job/node-test-pull-request/2012/ |
Heh... turns out there is a linting issue here afterall ;-) |
@@ -0,0 +1,50 @@ | |||
const common = require('../common.js'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
benchmark needs 'use strict';
at the top
8cfc0f8
to
72e7e68
Compare
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
72e7e68
to
e7246d1
Compare
Hi @jasnell , I updated the commit, and new benchmark result:
|
CI is green. LGTM |
@indutny ... any final comments on this before I land? |
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: #4790 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Brian White <mscdex@mscdex.net>
Landed in 089c6a4 |
@thealphanerd ... let's hold off landing this in v4 until it's been in v5 for a while. |
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: #4790 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Brian White <mscdex@mscdex.net>
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: #4790 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Brian White <mscdex@mscdex.net>
@jasnell should we include this in v4.5.0? |
It's likely safe |
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: #4790 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Brian White <mscdex@mscdex.net>
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: #4790 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Brian White <mscdex@mscdex.net>
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: #4790 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Brian White <mscdex@mscdex.net>
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