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

replace fast-uri url parser with URL contructor #144

Closed
wants to merge 4 commits into from

Conversation

synapse
Copy link

@synapse synapse commented Mar 12, 2024

Fixes #141

N.B. this fix replaces the current URIComponent with URL.

Checklist

Copy link
Member

@gurgunday gurgunday left a comment

Choose a reason for hiding this comment

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

Looks good to me, you can also remove the dependency I believe

@jsumners
Copy link
Member

I think there was an unanswered question in the referenced issue. Has that been addressed?

@gurgunday
Copy link
Member

Oh, that’s true, it might need a benchmark

const url = new URL(scheme + '://' + host + path)

if (key) return url[key]
return url
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 avoid the breaking change?

Copy link
Author

Choose a reason for hiding this comment

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

To avoid it, would mean converting the URL to an URIComponent object.
I can map it 1-to-1 and return what we previously had, but there's a s mall caveat where fast-uri previously also had a prop on the URIComponent called userinfo which returned something like this : "user:pass".
By default the URL does not have it, it would require creating ourselves just like as fast-uri does it.

Copy link
Member

Choose a reason for hiding this comment

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

nevermind

@mcollina
Copy link
Member

We should really have a benchmark to check if the breakage is worth the change.

Copy link
Member

@gurgunday gurgunday left a comment

Choose a reason for hiding this comment

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

Just blocking temporarily until we get a general benchmark, will try to look into it, but feel free to attach one if you can

@synapse
Copy link
Author

synapse commented Mar 13, 2024

Here are the benchmarks:

Code used

const fastUri = require('fast-uri');
const benchmark = require('benchmark')

const url = 'uri://user:pass@example.com:123/one/two.three?q1=a1&q2=a2#body';

new benchmark.Suite()
  .add('fast-uri', function () {
    fastUri.parse(url)
  })
  .add('url', function () {
    new URL(url)
  })
  .on('cycle', function (event) {
    console.log(String(event.target));
  })
  .on('complete', function () {
    console.log('Fastest is ' + this.filter('fastest').map('name'));
  })
  .run({ async: true });

Results run on Node version v20.11.1 LTS:

fast-uri x 2,588,130 ops/sec ±1.30% (95 runs sampled)
url x 2,910,301 ops/sec ±0.87% (93 runs sampled)
Fastest is url

fast-uri x 2,625,725 ops/sec ±0.36% (98 runs sampled)
url x 3,026,747 ops/sec ±0.33% (94 runs sampled)
Fastest is url

fast-uri x 2,651,826 ops/sec ±0.41% (98 runs sampled)
url x 3,029,741 ops/sec ±0.51% (92 runs sampled)
Fastest is url

Results run on Node version v18.19.1:

fast-uri x 2,522,467 ops/sec ±0.78% (97 runs sampled)
url x 2,730,338 ops/sec ±0.47% (94 runs sampled)
Fastest is url

fast-uri x 2,511,920 ops/sec ±0.73% (96 runs sampled)
url x 2,664,369 ops/sec ±0.45% (98 runs sampled)
Fastest is url

fast-uri x 2,486,801 ops/sec ±0.44% (97 runs sampled)
url x 2,700,008 ops/sec ±0.40% (96 runs sampled)
Fastest is url

@Uzlopak
Copy link
Contributor

Uzlopak commented Mar 13, 2024

Performance on node18?

Copy link
Member

@gurgunday gurgunday left a comment

Choose a reason for hiding this comment

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

lgtm

@Uzlopak, for this comment, I mean instantiation is what matters anyway, no? Ada returns the full object as far as I know, and property access is cheap; are these property getters?

@mcollina
Copy link
Member

As shown in other issues, it's important to actually benchmark the actual module, not the function in isolation.

@synapse
Copy link
Author

synapse commented Mar 14, 2024

You're absolutely right @mcollina I am already working on that as well. I'll also post the results soon.

@synapse
Copy link
Author

synapse commented Mar 14, 2024

Here is the benchmarks using it in fastify:

code used:

const benchmark = require('benchmark')
const Fastify = require('fastify')
const http = require('node:http')
const pluginFast = require('./plugin-fast');
const pluginUrl = require('../plugin');

async function getFastify(plugin, port) {
  const fastify = Fastify()
  fastify
    .register(plugin)
    .after((err) => {
      if (err) console.error(err)
    })
  
  fastify.get("/one", (req, reply) => {
    const uriData = req.urlData()
    reply.send()
  })

  try {
    await fastify.listen({ port })    
  } catch (err) {
    process.exit(1)
  }

  return fastify;
}

const bench = async () => {
  const fastifyPluginOld = await getFastify(pluginFast, 3201);
  const fastifyPluginNew = await getFastify(pluginUrl, 3202);

  new benchmark.Suite()
    .add('fast-uri', async function () {
      await fastifyPluginOld.inject({
        method: "GET",
        url: "/one?a=b&c=d#foo",
      })
    })
    .add('url', async function () {
      await fastifyPluginNew.inject({
            method: "GET",
            url: "/one?a=b&c=d#foo",
          })
    })
    .on('cycle', function (event) {
      console.log(String(event.target));
    })
    .on('complete', function () {
      console.log('Fastest is ' + this.filter('fastest').map('name'));
      fastifyPluginOld.close()
      fastifyPluginNew.close()
    })
    .run({async: true});
}

bench();

Results run on Node version v20.11.1 LTS:

fast-uri x 1,171,424 ops/sec ±8.73% (58 runs sampled)
url x 1,172,971 ops/sec ±7.79% (49 runs sampled)
Fastest is url,fast-uri

Results run on Node version v18.19.1:

fast-uri x 1,388,169 ops/sec ±18.89% (50 runs sampled)
url x 1,366,116 ops/sec ±20.89% (37 runs sampled)
Fastest is fast-uri,url

@synapse synapse requested a review from mcollina March 19, 2024 09:19
@mcollina
Copy link
Member

Given it has no significant gain, I don't think changing the module API is worth it.

@kibertoad
Copy link
Member

@mcollina reducing amount of dependencies is not a good thing on its own?

@mcollina
Copy link
Member

But it's not. fast-uri is a dependency of fastify and it would keep being one.

@jsumners
Copy link
Member

Given lack of movement, and the conclusions by Matteo, I am closing this.

@jsumners jsumners closed this Jun 26, 2024
@Fdawgs Fdawgs mentioned this pull request Oct 5, 2024
2 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

use new URL instead of fast-uri
6 participants