url: refactor isIpv6Hostname function to use string methods#54486
url: refactor isIpv6Hostname function to use string methods#54486rayark1 wants to merge 1 commit intonodejs:mainfrom
Conversation
Refactored the isIpv6Hostname function to improve readability and performance
|
Review requested:
|
| StringPrototypeCharCodeAt(hostname, hostname.length - 1) === | ||
| CHAR_RIGHT_SQUARE_BRACKET | ||
| ); | ||
| return hostname.startsWith('[') && hostname.endsWith(']'); |
There was a problem hiding this comment.
What about the primordials? Are they not important?
CC @nodejs/primordials
There was a problem hiding this comment.
How Is using startsWith and endsWith can be considered being faster as it claims that it has even better performance?
|
Can you provide a benchmark to show the performance improvement? |
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## main #54486 +/- ##
==========================================
- Coverage 87.34% 87.33% -0.01%
==========================================
Files 649 649
Lines 182544 182537 -7
Branches 35030 35032 +2
==========================================
- Hits 159445 159425 -20
- Misses 16372 16375 +3
- Partials 6727 6737 +10
|
ronag
left a comment
There was a problem hiding this comment.
This is just going back to how it was before. I don't think we should be going back and forth between the same things.
Do we have benchmarks? |
Uzlopak
left a comment
There was a problem hiding this comment.
How Is using startsWith and endsWith can be considered being faster as it claims that it has even better performance?
I doubt that this has any performance gains. More likeliy performance regressions.
Should be rejected.
|
For completeness: 'use strict';
const common = require('../common.js');
const { isIpv6Hostname } = require('url');
const bench = common.createBenchmark(main, {
value: [
'[::1]',
'127.0.0.1',
'example.org'
],
n: [1e6],
});
function main({ n, value }) {
bench.start();
for (let i = 0; i < n; ++i)
isIpv6Hostname(value);
bench.end(n);
}and i exposed is isIpv6Hostname in url.js This PR: aras@aras-Lenovo-Legion-5-17ARH05H:~/workspace/node$ ./node benchmark/url/url-isIpv6hostname.js
url/url-isIpv6hostname.js n=1000000 value="[::1]": 129,560,278.89145634
url/url-isIpv6hostname.js n=1000000 value="127.0.0.1": 194,712,162.8510222
url/url-isIpv6hostname.js n=1000000 value="example.org": 198,888,017.09641397Main: So in case that it is encapsulated in brackets we lose about 50% performance and in other cases we lose few percents because of startsWith is slower than directly checking the first character. THe fastest implementation would be by avoiding .: function isIpv6Hostname(hostname) {
return (
hostname[0] === CHAR_LEFT_SQUARE_BRACKET &&
hostname[hostname.length - 1] ===
CHAR_RIGHT_SQUARE_BRACKET
);
}with: aras@aras-Lenovo-Legion-5-17ARH05H:~/workspace/node$ ./node benchmark/url/url-isIpv6hostname.js
url/url-isIpv6hostname.js n=1000000 value="[::1]": 387,195,446.5815482
url/url-isIpv6hostname.js n=1000000 value="127.0.0.1": 305,417,184.60330886
url/url-isIpv6hostname.js n=1000000 value="example.org": 361,797,773.1347063Is the need for primordials really needed for an internal function where it is ensured, that we only pass strings? |
|
@Uzlopak especially for an internal function, in which it could easily be a security issue to provide a hook point for user code - even if it's only ever passed strings (which could also change in the future) the string methods are globally replaceable. |
|
To be honest... i looked into the code and i had to laugh. |
Refactor the isIpv6Hostname function to improve readability and performance