Skip to content
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: spec-compliant URLSearchParams serializer #11626

Closed
wants to merge 2 commits into from

Conversation

TimothyGu
Copy link
Member

@TimothyGu TimothyGu commented Mar 1, 2017

Differences with querystring module (which the serializer currently depends on):

code point querystring spec
U+0020   %20 +
U+0027 ' ' %27
U+0028 ( ( %28
U+0029 ) ) %29
U+007E ~ ~ %7E

A C++ implementation cannot seem to reach the JS version's performance.

Benchmark: before vs. after
                                                                                                    improvement confidence      p.value
 url/legacy-vs-whatwg-url-searchparams-serialize.js n=1000000 method="whatwg" type="altspaces"          56.97 %        *** 1.131841e-33
 url/legacy-vs-whatwg-url-searchparams-serialize.js n=1000000 method="whatwg" type="encodefake"         85.79 %        *** 8.380179e-49
 url/legacy-vs-whatwg-url-searchparams-serialize.js n=1000000 method="whatwg" type="encodelast"        133.54 %        *** 4.568047e-52
 url/legacy-vs-whatwg-url-searchparams-serialize.js n=1000000 method="whatwg" type="encodemany"        136.69 %        *** 3.839133e-66
 url/legacy-vs-whatwg-url-searchparams-serialize.js n=1000000 method="whatwg" type="manyblankpairs"    102.90 %        *** 2.115923e-35
 url/legacy-vs-whatwg-url-searchparams-serialize.js n=1000000 method="whatwg" type="manypairs"         423.66 %        *** 2.121638e-43
 url/legacy-vs-whatwg-url-searchparams-serialize.js n=1000000 method="whatwg" type="multicharsep"      136.13 %        *** 1.320596e-54
 url/legacy-vs-whatwg-url-searchparams-serialize.js n=1000000 method="whatwg" type="multivalue"         88.71 %        *** 1.524783e-59
 url/legacy-vs-whatwg-url-searchparams-serialize.js n=1000000 method="whatwg" type="multivaluemany"     25.24 %        *** 3.994424e-41
 url/legacy-vs-whatwg-url-searchparams-serialize.js n=1000000 method="whatwg" type="noencode"          135.61 %        *** 3.251158e-44
Benchmark: legacy (querystring) vs. WHATWG
url/legacy-vs-whatwg-url-searchparams-serialize.js n=1000000 method="legacy" type="noencode": 2,671,975.4115417274
url/legacy-vs-whatwg-url-searchparams-serialize.js n=1000000 method="whatwg" type="noencode": 3,008,967.4994620117
url/legacy-vs-whatwg-url-searchparams-serialize.js n=1000000 method="legacy" type="multicharsep": 2,615,972.2291527316
url/legacy-vs-whatwg-url-searchparams-serialize.js n=1000000 method="whatwg" type="multicharsep": 2,885,936.0222384227
url/legacy-vs-whatwg-url-searchparams-serialize.js n=1000000 method="legacy" type="encodefake": 1,493,426.4438126145
url/legacy-vs-whatwg-url-searchparams-serialize.js n=1000000 method="whatwg" type="encodefake": 1,641,878.4775006676
url/legacy-vs-whatwg-url-searchparams-serialize.js n=1000000 method="legacy" type="encodemany": 2,565,969.8400934297
url/legacy-vs-whatwg-url-searchparams-serialize.js n=1000000 method="whatwg" type="encodemany": 3,025,840.9510215684
url/legacy-vs-whatwg-url-searchparams-serialize.js n=1000000 method="legacy" type="encodelast": 2,613,356.200269775
url/legacy-vs-whatwg-url-searchparams-serialize.js n=1000000 method="whatwg" type="encodelast": 2,901,369.8722106437
url/legacy-vs-whatwg-url-searchparams-serialize.js n=1000000 method="legacy" type="multivalue": 2,615,576.6498150555
url/legacy-vs-whatwg-url-searchparams-serialize.js n=1000000 method="whatwg" type="multivalue": 2,502,413.2021715143
url/legacy-vs-whatwg-url-searchparams-serialize.js n=1000000 method="legacy" type="multivaluemany": 1,383,932.6225206275
url/legacy-vs-whatwg-url-searchparams-serialize.js n=1000000 method="whatwg" type="multivaluemany": 985,021.4923070684
url/legacy-vs-whatwg-url-searchparams-serialize.js n=1000000 method="legacy" type="manypairs": 399,773.9756297489
url/legacy-vs-whatwg-url-searchparams-serialize.js n=1000000 method="whatwg" type="manypairs": 804,542.90558165
url/legacy-vs-whatwg-url-searchparams-serialize.js n=1000000 method="legacy" type="manyblankpairs": 14,459,573.094118012
url/legacy-vs-whatwg-url-searchparams-serialize.js n=1000000 method="whatwg" type="manyblankpairs": 10,583,700.054130334
url/legacy-vs-whatwg-url-searchparams-serialize.js n=1000000 method="legacy" type="altspaces": 1,092,358.4670786818
url/legacy-vs-whatwg-url-searchparams-serialize.js n=1000000 method="whatwg" type="altspaces": 1,174,023.8424377916
Checklist
  • make -j4 test (UNIX), or vcbuild test (Windows) passes
  • tests and/or benchmarks are included
  • documentation is changed or added
  • commit message follows commit guidelines
Affected core subsystem(s)

url

@nodejs-github-bot nodejs-github-bot added dont-land-on-v4.x whatwg-url Issues and PRs related to the WHATWG URL implementation. labels Mar 1, 2017
@TimothyGu
Copy link
Member Author

@jasnell
Copy link
Member

jasnell commented Mar 1, 2017

Awesome! Will take a look at it in detail tomorrow

// Ref: https://url.spec.whatwg.org/#concept-urlencoded-serializer
function serializeParams(array) {
const len = array.length;
if (!len)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: len === 0 to avoid conversion to boolean

return '';

var output = `${escapeParam(array[0])}=${escapeParam(array[1])}`;
for (var i = 2; i < array.length; i += 2)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: use len also here or do not create it earlier

@@ -154,7 +154,7 @@ test(function() {
}, "Constructor with sequence of sequences of strings");

[
// { "input": {"+": "%C2"}, "output": [[" ", "\uFFFD"]], "name": "object with +" },
{ "input": {"+": "%C2"}, "output": [["+", "%C2"]], "name": "object with +" },
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you update the Refs SHA? This fix was in e94c604

Copy link
Member

@joyeecheung joyeecheung left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work! Feel good to see the tests get uncommented =)


// ASCII
if (c < 0x80) {
if (noEscapeParam[c] === 1)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Maybe noEscapeTable? The name noEscapeParam together with the function name escapeParam looks a bit weird..

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah... I agree. Used the more standard noEscape instead.

out += str.slice(lastPos, i);
lastPos = i + 1;
if (c === 0x20)
out += '+';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another way would be to fork the hexTable too with hexTable[0x20] = '+'..not sure how much that would gain though.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice, that does bring some speedup (consistently 1-2% for altspace benchmark).

@TimothyGu TimothyGu force-pushed the urlsearchparams-serialize branch 2 times, most recently from 805fbcf to b05e5de Compare March 4, 2017 02:26
@TimothyGu
Copy link
Member Author

@targos, @joyeecheung, PR updated to address comments.

CI: https://ci.nodejs.org/job/node-test-pull-request/6697/

@joyeecheung
Copy link
Member

Still LGTM

@TimothyGu TimothyGu requested a review from jasnell March 6, 2017 05:15
@TimothyGu
Copy link
Member Author

@jasnell PTAL...

@joyeecheung
Copy link
Member

joyeecheung commented Mar 14, 2017

Ping @jasnell @targos

Copy link
Member

@jasnell jasnell left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My apologies on the late review.. been a bit distracted. This LGTM so long as CI is green :-)

@TimothyGu
Copy link
Member Author

@TimothyGu
Copy link
Member Author

CI is actually passing. Landed in d77a758. Thanks all.

@TimothyGu TimothyGu closed this Mar 14, 2017
@TimothyGu TimothyGu deleted the urlsearchparams-serialize branch March 14, 2017 20:15
@TimothyGu TimothyGu restored the urlsearchparams-serialize branch March 14, 2017 20:15
TimothyGu added a commit to TimothyGu/node that referenced this pull request Mar 14, 2017
PR-URL: nodejs#11626
Reviewed-By: Joyee Cheung <[email protected]>
Reviewed-By: Michaël Zasso <[email protected]>
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Daijiro Wachi <[email protected]>
@TimothyGu TimothyGu deleted the urlsearchparams-serialize branch March 14, 2017 20:29
@italoacasas
Copy link
Contributor

@TimothyGu this is not landing in v7.x-staging because git conflicts.

Question: do you have a list of all the URL commits that need backport?

jungx098 pushed a commit to jungx098/node that referenced this pull request Mar 21, 2017
PR-URL: nodejs#11626
Reviewed-By: Joyee Cheung <[email protected]>
Reviewed-By: Michaël Zasso <[email protected]>
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Daijiro Wachi <[email protected]>
@jasnell jasnell mentioned this pull request Apr 4, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
whatwg-url Issues and PRs related to the WHATWG URL implementation.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants