-
Notifications
You must be signed in to change notification settings - Fork 30k
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
url: reduce deplicated codes in autoEscapeStr
#18613
Conversation
@starkwang I guess it might have a minor performance penalty but without having a significant impact. Would you be so kind and provide some benchmarks for it nevertheless? :-) |
@BridgeAR Pushed commit to fix performance regression. Here is the benchmark:
|
lib/url.js
Outdated
34: '%22', 39: '%27', 60: '%3C', 62: '%3E', | ||
92: '%5C', 94: '%5E', 96: '%60', 123: '%7B', | ||
124: '%7C', 125: '%7D' | ||
}; | ||
function autoEscapeStr(rest) { | ||
var escaped = ''; | ||
var lastEscapedPos = 0; | ||
for (var i = 0; i < rest.length; ++i) { | ||
// Manual switching is faster than using a Map/Object. |
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.
Isn't the whole point of having these switch statements to avoid the overhead of accessing a Map
/object? (although that looks quite Crankshaftscript-ish so I doubt if the comment here still holds)...if we are going to access an object anyway, then the switch statements can just be replaced with something like const code = escapedCharacterCodes[rest.charCodeAt(i)]; if (code)...
, and this comment can be removed.
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.
That's exactly what I do in the first commit, but it causes ~10% performance regression in url.parse
.
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.
@bmeurer Would you be interested in taking a look at this?
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.
Intuitively I'd suggest to go with an array instead of an object literal. Did you try with an array?
|
@bmeurer @joyeecheung I tried to use array and found it was faster. Here is the benchmark with array:
|
lib/url.js
Outdated
const escapedCodesArr = new Array(); | ||
for (var key in escapedCodes) { | ||
escapedCodesArr[key] = escapedCodes[key]; | ||
} |
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.
Is a holey array as fast as a dense array? I expect it would be better to add empty entries instead of having holes?
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 seems that dense array is still faster than holey array: https://jsperf.com/packed-vs-holey-arrays
But the comparison above is between the array case and the original switch
case.
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.
Would you be so kind and switch to the dense array in that case? :-)
I guess we do not need a new benchmark in that case even though it would of course still be nice to have the results with those.
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.
Sorry I don't fully understand. The code of chars in rest
is not dense, so the array used to map them is not dense as well. Changing it to a dense array may cost a lot.
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.
What I meant is to use it like e.g. util.js.
CI before land: https://ci.nodejs.org/job/node-test-pull-request/13327/ |
Landed in 3cef3e6 |
PR-URL: #18613 Reviewed-By: Ruben Bridgewater <[email protected]>
PR-URL: nodejs#18613 Reviewed-By: Ruben Bridgewater <[email protected]>
PR-URL: #18613 Reviewed-By: Ruben Bridgewater <[email protected]>
PR-URL: nodejs#18613 Reviewed-By: Ruben Bridgewater <[email protected]>
Checklist
make -j4 test
(UNIX), orvcbuild test
(Windows) passesAffected core subsystem(s)
url