Skip to content

Conversation

@D-Sketon
Copy link
Member

check list

  • Add test cases for the changes.
  • Passed the CI test.

Description

close #439

Additional information

clk: ~3.84 GHz
cpu: 13th Gen Intel(R) Core(TM) i5-13400F
runtime: node 24.8.0 (x64-win32)

benchmark                   avg (min … max) p75 / p99    (min … top 1%)
------------------------------------------- -------------------------------
• http://user:[email protected]/
------------------------------------------- -------------------------------
origin                        10.96 µs/iter  10.20 µs    █
                      (6.30 µs … 549.50 µs)  29.30 µs   ▂█
                    ( 56.00  b … 458.25 kb)   2.53 kb ▁▁██▃▃▂▂▂▂▂▁▁▁▁▁▁▁▁▁▁

optimize                       1.89 µs/iter   1.95 µs   █
                        (1.68 µs … 2.65 µs)   2.61 µs  ▅██  ▃
                    (647.34  b … 659.66  b) 656.10  b ▅████▄█▄▂▃█▃▁▁▁▂▁▂▁▁▂

summary
  optimize
   5.79x faster than origin

• https://foo.com/
------------------------------------------- -------------------------------
origin                         9.81 µs/iter   8.90 µs    █
                      (6.20 µs … 313.90 µs)  22.40 µs   ▆█
                    (  1.80 kb … 267.74 kb)   1.97 kb ▁▂██▃▂▂▂▂▂▃▂▂▁▁▁▁▁▁▁▁

optimize                       1.55 µs/iter   1.56 µs   █
                        (1.31 µs … 2.49 µs)   2.38 µs  ▅███
                    (583.81  b … 592.55  b) 592.02  b ██████▄▃▃▂▂▂▃▂▁▃▃▂▁▁▃

summary
  optimize
   6.31x faster than origin

• http://example.com/normal/path?query=value&another=value#fragment
------------------------------------------- -------------------------------
origin                        11.97 µs/iter  11.00 µs  █
                      (8.90 µs … 300.50 µs)  37.20 µs  █
                    (112.00  b … 408.39 kb)   3.31 kb ▁█▃▃▂▁▂▁▁▁▁▁▁▁▁▁▁▁▁▁▁

optimize                       5.02 µs/iter   5.86 µs                    █
                        (2.75 µs … 6.38 µs)   6.03 µs                   ▅█
                    (  1.38 kb …   1.39 kb)   1.39 kb █▃▃▃▁▃▁▃▁▃▁▃▃▁▁▁▃▁███

summary
  optimize
   2.39x faster than origin

• data:text/plain;base64,SGVsbG8sIFdvcmxkIQ==
------------------------------------------- -------------------------------
origin                        16.09 µs/iter  16.08 µs              █       
                      (15.30 µs … 19.43 µs)  16.52 µs ▅▅ ▅▅▅  ▅ ▅ ▅█      ▅
                    (  1.08 kb …   1.08 kb)   1.08 kb ██▁███▁▁█▁█▁██▁▁▁▁▁▁█

optimize                     848.02 ns/iter 853.96 ns        █
                      (442.19 ns … 2.20 µs)   1.45 µs        █▆
                    (296.64  b … 589.52  b) 306.31  b ▁▁▁▁▁▁▅██▅▄▂▂▁▁▁▂▁▁▁▂

summary
  optimize
   18.97x faster than origin

• /relative/path?query=value&another=value#fragment
------------------------------------------- -------------------------------
origin                        18.07 µs/iter  17.60 µs    █
                     (13.10 µs … 292.40 µs)  43.00 µs    █
                    (816.00  b … 431.73 kb)   1.31 kb ▁▁██▃▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁

optimize                       1.22 µs/iter   1.27 µs              █
                      (652.88 ns … 1.55 µs)   1.45 µs              ███
                    (138.76  b … 444.53  b) 148.11  b ▃▁▁▁▁▂▂▁▁▁▁▁▁█████▃▂▂

summary
  optimize
   14.82x faster than origin
PS D:\hexo\hexojs\hexo-util> npx tsx .\mitata.ts
npm warn Unknown user config "home". This will stop working in the next major version of npm.
clk: ~3.96 GHz
cpu: 13th Gen Intel(R) Core(TM) i5-13400F
runtime: node 24.8.0 (x64-win32)

benchmark                   avg (min … max) p75 / p99    (min … top 1%)
------------------------------------------- -------------------------------
• http://user:[email protected]/
------------------------------------------- -------------------------------
origin                         9.66 µs/iter   9.40 µs     █
                      (5.80 µs … 304.00 µs)  21.50 µs     █▄
                    (112.00  b … 538.48 kb)   2.48 kb ▁▁▁▆██▂▁▁▁▁▁▁▁▁▁▁▁▁▁▁

optimize                       1.76 µs/iter   1.80 µs          █
                        (1.59 µs … 1.94 µs)   1.93 µs        ▄██▇▂ ▂
                    (647.34  b … 659.69  b) 656.12  b ▄▅▂▄▂▁▆███████▆▅▂▂▅▁▄

summary
  optimize
   5.5x faster than origin

• https://foo.com/
------------------------------------------- -------------------------------
origin                         7.52 µs/iter   8.33 µs  █  ▂
                        (6.66 µs … 8.66 µs)   8.52 µs  █  █              ▅▅
                    (713.31  b …   1.88 kb)   1.37 kb ▇█▇▇█▇▁▁▁▁▁▁▁▁▁▇▁▇▇██

optimize                       1.39 µs/iter   1.43 µs         ▂▆ █  ▄
                        (1.25 µs … 1.67 µs)   1.53 µs   █▃▃▅▅▃██▆█▆██
                    (534.69  b … 592.56  b) 591.55  b ▅▇█████████████▇▇▅▅▇▃

summary
  optimize
   5.43x faster than origin

• http://example.com/normal/path?query=value&another=value#fragment
------------------------------------------- -------------------------------
origin                        10.26 µs/iter  10.10 µs   █
                      (8.40 µs … 276.70 µs)  24.80 µs  ██
                    (512.00  b … 398.87 kb)   3.14 kb ▂██▂▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁

optimize                       2.77 µs/iter   2.82 µs       ▅▅█
                        (2.56 µs … 3.04 µs)   3.03 µs  ▂   ▂███▂▇▅▇
                    (  1.38 kb …   1.39 kb)   1.39 kb ▄█▁▇▇████████▁▄▇▇▁▁▄▄

summary
  optimize
   3.71x faster than origin

• data:text/plain;base64,SGVsbG8sIFdvcmxkIQ==
------------------------------------------- -------------------------------
origin                         9.05 µs/iter   9.54 µs  █
                       (8.44 µs … 10.16 µs)  10.02 µs  █ █
                    (  1.07 kb …   1.08 kb)   1.08 kb ██████▁█▁▁▁█▁▁███▁▁▁█

optimize                     355.97 ns/iter 366.67 ns      █
                    (317.55 ns … 479.49 ns) 453.32 ns  ▃   ██▆
                    (176.24  b … 528.98  b) 304.13  b ███▆▄████▆▄▃▃▃▂▂▂▁▁▁▁

summary
  optimize
   25.41x faster than origin

• /relative/path?query=value&another=value#fragment
------------------------------------------- -------------------------------
origin                         8.57 µs/iter   8.82 µs    █
                       (7.70 µs … 10.10 µs)   9.96 µs  █ █ █              █
                    (806.97  b … 826.17  b) 815.96  b ████▁██▁▁██▁▁▁▁▁█▁▁▁█

optimize                     637.45 ns/iter 645.87 ns       ▇█▃
                    (567.55 ns … 906.37 ns) 741.31 ns      ▄███▇
                    (136.57  b … 350.26  b) 146.07  b ▂▁▃▁▇█████▇▅▄▆▅▂▂▁▂▁▁

summary
  optimize
   13.45x faster than origin


const decodeURL = (str: string) => {
if (parse(str).protocol) {
if (hasProtocolLikeNode(str)) {
Copy link
Member

Choose a reason for hiding this comment

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

If we are going to implement some loose check, why not just if (str.includes('://')?

Copy link
Member Author

@D-Sketon D-Sketon Oct 11, 2025

Choose a reason for hiding this comment

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

No, using str.includes('://') fails the unit tests.
{92E0351B-DE8D-4E55-87E9-7367053CFC09}

Copy link
Member

Choose a reason for hiding this comment

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

I am still not a fan of copying some regexp. How would we know if it is spec-compliant or not?

Copy link
Member Author

Choose a reason for hiding this comment

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

This regexp is from nodejs https://github.com/nodejs/node/blob/a1244f04dea9148c44fd6daf60b5105f7a85ea12/lib/url.js#L96, and it is stricter than the one in RFC 3986 (https://www.rfc-editor.org/rfc/rfc3986#appendix-B). The regex in RFC 3986 is /^(([^:/?#]+):)/.

Copy link
Member

Choose a reason for hiding this comment

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

But whathappened if Node.js changes their implementation (maybe a ReDoS attack is discovered, maybe a CSRF PoC is created, and there is a new CVE created), how can we make sure our copied regexp is up to date?

Copy link
Member Author

Choose a reason for hiding this comment

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

Since there is such a concern, let's consider a less radical optimization method.

@coveralls
Copy link

Coverage Status

coverage: 96.527% (-0.3%) from 96.839%
when pulling 3721771 on D-Sketon:perf/3.3.0-2
into 23521a6 on hexojs:master.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

More efficient encode_url

3 participants