Skip to content

Commit 1c3df96

Browse files
committed
fs: replace regexp with function
Replacing the path separator-finding regexp with a custom function results in a measurable improvement in performance. PR-URL: #10789 Reviewed-By: James M Snell <[email protected]> Reviewed-By: Michaël Zasso <[email protected]> Reviewed-By: Michael Dawson <[email protected]> Reviewed-By: Matteo Collina <[email protected]> Reviewed-By: Benjamin Gruenbaum <[email protected]>
1 parent 34c9fc2 commit 1c3df96

File tree

1 file changed

+37
-16
lines changed

1 file changed

+37
-16
lines changed

lib/fs.js

+37-16
Original file line numberDiff line numberDiff line change
@@ -1478,12 +1478,6 @@ fs.unwatchFile = function(filename, listener) {
14781478
};
14791479

14801480

1481-
// Regexp that finds the next portion of a (partial) path
1482-
// result is [base_with_slash, base], e.g. ['somedir/', 'somedir']
1483-
const nextPartRe = isWindows ?
1484-
/(.*?)(?:[/\\]+|$)/g :
1485-
/(.*?)(?:[/]+|$)/g;
1486-
14871481
// Regex to find the device root, including trailing slash. E.g. 'c:\\'.
14881482
const splitRootRe = isWindows ?
14891483
/^(?:[a-zA-Z]:|[\\/]{2}[^\\/]+[\\/][^\\/]+)?[\\/]*/ :
@@ -1500,6 +1494,21 @@ function encodeRealpathResult(result, options) {
15001494
}
15011495
}
15021496

1497+
// Finds the next portion of a (partial) path, up to the next path delimiter
1498+
var nextPart;
1499+
if (isWindows) {
1500+
nextPart = function nextPart(p, i) {
1501+
for (; i < p.length; ++i) {
1502+
const ch = p.charCodeAt(i);
1503+
if (ch === 92/*'\'*/ || ch === 47/*'/'*/)
1504+
return i;
1505+
}
1506+
return -1;
1507+
};
1508+
} else {
1509+
nextPart = function nextPart(p, i) { return p.indexOf('/', i); };
1510+
}
1511+
15031512
fs.realpathSync = function realpathSync(p, options) {
15041513
options = getOptions(options, {});
15051514
handleError((p = getPathFromURL(p)));
@@ -1544,12 +1553,18 @@ fs.realpathSync = function realpathSync(p, options) {
15441553
// NB: p.length changes.
15451554
while (pos < p.length) {
15461555
// find the next part
1547-
nextPartRe.lastIndex = pos;
1548-
var result = nextPartRe.exec(p);
1556+
var result = nextPart(p, pos);
15491557
previous = current;
1550-
current += result[0];
1551-
base = previous + result[1];
1552-
pos = nextPartRe.lastIndex;
1558+
if (result === -1) {
1559+
var last = p.slice(pos);
1560+
current += last;
1561+
base = previous + last;
1562+
pos = p.length;
1563+
} else {
1564+
current += p.slice(pos, result + 1);
1565+
base = previous + p.slice(pos, result);
1566+
pos = result + 1;
1567+
}
15531568

15541569
// continue if not a symlink
15551570
if (knownHard[base] || (cache && cache.get(base) === base)) {
@@ -1658,12 +1673,18 @@ fs.realpath = function realpath(p, options, callback) {
16581673
}
16591674

16601675
// find the next part
1661-
nextPartRe.lastIndex = pos;
1662-
var result = nextPartRe.exec(p);
1676+
var result = nextPart(p, pos);
16631677
previous = current;
1664-
current += result[0];
1665-
base = previous + result[1];
1666-
pos = nextPartRe.lastIndex;
1678+
if (result === -1) {
1679+
var last = p.slice(pos);
1680+
current += last;
1681+
base = previous + last;
1682+
pos = p.length;
1683+
} else {
1684+
current += p.slice(pos, result + 1);
1685+
base = previous + p.slice(pos, result);
1686+
pos = result + 1;
1687+
}
16671688

16681689
// continue if not a symlink
16691690
if (knownHard[base]) {

0 commit comments

Comments
 (0)