txtdot icon indicating copy to clipboard operation
txtdot copied to clipboard

Performance: string methods instead of `new URL`

Open DarkCat09 opened this issue 2 years ago • 1 comments

We'll get a really good performance boost if we replace new URL, which is used too much often as I see, with string methods. On the other hand, manually parsing URL in some cases is not simple and concise.

Benchmark code
const Benchmarkify = require("benchmarkify")

const benchmark = new Benchmarkify("Benchmark", { chartImage: true }).printHeader()

benchmark.createSuite("URL convert", { time: 10000 })

  .add("URL object", () => {
                const url = new URL("https://dc09.ru/posts/fediverse#comments")
                const hash = url.hash
                url.hash = ""
                return encodeURIComponent(url.toString()) + hash
        })

        .ref("String methods", () => {
                let url = "https://dc09.ru/posts/fediverse#comments"
                const hashIdx = url.indexOf("#")
                if (hashIdx != -1) {
                        return encodeURIComponent(url.substring(0, hashIdx)) + url.substring(hashIdx)
                }
                else {
                        return encodeURIComponent(url)
                }
        })

benchmark.run()
Benchmark results
Platform info:
==============
   Linux 6.7.4-artix1-1 x64
   Node.JS: 21.6.1
   V8: 11.8.172.17-node.19
   CPU: Intel(R) Core(TM) i5-10400 CPU @ 2.90GHz × 12
   Memory: 30 GB

Suite: URL convert
==================

✔ URL object         1 176 230 ops/sec
✔ String methods     4 825 419 ops/sec

   URL object           -75,62%   (1 176 230 ops/sec)   (avg: 850ns)
   String methods (#)        0%   (4 825 419 ops/sec)   (avg: 207ns)

┌────────────────┬────────────────────────────────────────────────────┐
│ URL object     │ ████████████                                       │
├────────────────┼────────────────────────────────────────────────────┤
│ String methods │ ██████████████████████████████████████████████████ │
└────────────────┴────────────────────────────────────────────────────┘

DarkCat09 avatar Feb 14 '24 10:02 DarkCat09

We can use fast-url-parser.

Benchmark code
const Benchmarkify = require("benchmarkify");
const furl = require("fast-url-parser");

const benchmark = new Benchmarkify("Benchmark", {
  chartImage: true,
}).printHeader();

benchmark
  .createSuite("URL convert", { time: 10000 })
  .add("URL object", () => {
    const url = new URL("https://dc09.ru/posts/fediverse#comments");
    const hash = url.hash;
    url.hash = "";
    return encodeURIComponent(url.toString()) + hash;
  })
  .ref("Fast URL parser", () => {
    const url = furl.parse("https://dc09.ru/posts/fediverse#comments");
    const hash = url.hash;
    url.hash = "";
    return encodeURIComponent(url.toString()) + hash;
  })
  .ref("String methods", () => {
    let url = "https://dc09.ru/posts/fediverse#comments";
    const hashIdx = url.indexOf("#");
    if (hashIdx != -1) {
      return (
        encodeURIComponent(url.substring(0, hashIdx)) + url.substring(hashIdx)
      );
    } else {
      return encodeURIComponent(url);
    }
  });

benchmark.run();
Benchmark results
Suite: URL convert
==================

✔ URL object            930,889 ops/sec
✔ Fast URL parser     2,423,227 ops/sec
✔ String methods      3,738,100 ops/sec

   URL object             -75.1%    (930,889 ops/sec)   (avg: 1μs)
   Fast URL parser       -35.17%   (2,423,227 ops/sec)   (avg: 412ns)
   String methods (#)         0%   (3,738,100 ops/sec)   (avg: 267ns)

┌─────────────────┬────────────────────────────────────────────────────┐
│ URL object      │ ████████████                                       │
├─────────────────┼────────────────────────────────────────────────────┤
│ Fast URL parser │ ████████████████████████████████                   │
├─────────────────┼────────────────────────────────────────────────────┤
│ String methods  │ ██████████████████████████████████████████████████ │
└─────────────────┴────────────────────────────────────────────────────┘

artegoser avatar Feb 17 '24 10:02 artegoser