url: reduce deplicated codes in autoEscapeStr#18613
url: reduce deplicated codes in autoEscapeStr#18613starkwang wants to merge 5 commits intonodejs:masterfrom
autoEscapeStr#18613Conversation
|
@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
| 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.
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.
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.
@bmeurer Would you be interested in taking a look at this?
There was a problem hiding this comment.
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.
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.
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.
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.
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.
|
CI before land: https://ci.nodejs.org/job/node-test-pull-request/13327/ |
|
Landed in 3cef3e6 |
PR-URL: #18613 Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
PR-URL: nodejs#18613 Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
PR-URL: #18613 Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
PR-URL: nodejs#18613 Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Checklist
make -j4 test(UNIX), orvcbuild test(Windows) passesAffected core subsystem(s)
url