Skip to content

Commit cc4d66e

Browse files
committed
path: faster posix path.resolve() without arguments
This is frequently called as alternative to process.cwd(). That is the main motivation for improving the performance of that use case.
1 parent ff3a028 commit cc4d66e

File tree

7 files changed

+24
-15
lines changed

7 files changed

+24
-15
lines changed

benchmark/path/join-posix.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ function main({ n, paths }) {
1616

1717
bench.start();
1818
for (let i = 0; i < n; i++) {
19-
if (i % 3 === 0) {
20-
copy[1] = `${orig}${i}`;
19+
if (i % 5 === 0) {
20+
copy[1] = `${orig}/${i}`;
2121
posix.join(...copy);
2222
} else {
2323
posix.join(...args);

benchmark/path/join-win32.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ function main({ n, paths }) {
1616

1717
bench.start();
1818
for (let i = 0; i < n; i++) {
19-
if (i % 3 === 0) {
20-
copy[1] = `${orig}${i}`;
19+
if (i % 5 === 0) {
20+
copy[1] = `${orig}\\${i}`;
2121
win32.join(...copy);
2222
} else {
2323
win32.join(...args);

benchmark/path/normalize-posix.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ const bench = common.createBenchmark(main, {
1717
function main({ n, path }) {
1818
bench.start();
1919
for (let i = 0; i < n; i++) {
20-
posix.normalize(i % 3 === 0 ? `${path}${i}` : path);
20+
posix.normalize(i % 5 === 0 ? `${path}/${i}` : path);
2121
}
2222
bench.end(n);
2323
}

benchmark/path/normalize-win32.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ const bench = common.createBenchmark(main, {
1717
function main({ n, path }) {
1818
bench.start();
1919
for (let i = 0; i < n; i++) {
20-
win32.normalize(i % 3 === 0 ? `${path}${i}` : path);
20+
win32.normalize(i % 5 === 0 ? `${path}\\${i}` : path);
2121
}
2222
bench.end(n);
2323
}

benchmark/path/resolve-posix.js

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,23 +4,25 @@ const { posix } = require('path');
44

55
const bench = common.createBenchmark(main, {
66
paths: [
7+
'empty',
78
'',
89
['', ''].join('|'),
910
['foo/bar', '/tmp/file/', '..', 'a/../subfile'].join('|'),
1011
['a/b/c/', '../../..'].join('|'),
12+
['/a/b/c/', 'abc'].join('|'),
1113
],
1214
n: [1e5],
1315
});
1416

1517
function main({ n, paths }) {
16-
const args = paths.split('|');
18+
const args = paths === 'empty' ? [] : paths.split('|');
1719
const copy = [...args];
18-
const orig = copy[0];
20+
const orig = copy[0] ?? '';
1921

2022
bench.start();
2123
for (let i = 0; i < n; i++) {
22-
if (i % 3 === 0) {
23-
copy[0] = `${orig}${i}`;
24+
if (i % 5 === 0) {
25+
copy[0] = `${orig}/${i}`;
2426
posix.resolve(...copy);
2527
} else {
2628
posix.resolve(...args);

benchmark/path/resolve-win32.js

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ const { win32 } = require('path');
44

55
const bench = common.createBenchmark(main, {
66
paths: [
7+
'empty',
78
'',
89
['', ''].join('|'),
910
['c:/ignore', 'd:\\a/b\\c/d', '\\e.exe'].join('|'),
@@ -13,14 +14,14 @@ const bench = common.createBenchmark(main, {
1314
});
1415

1516
function main({ n, paths }) {
16-
const args = paths.split('|');
17+
const args = paths === 'empty' ? [] : paths.split('|');
1718
const copy = [...args];
18-
const orig = copy[0];
19+
const orig = copy[0] ?? '';
1920

2021
bench.start();
2122
for (let i = 0; i < n; i++) {
22-
if (i % 3 === 0) {
23-
copy[0] = `${orig}${i}`;
23+
if (i % 5 === 0) {
24+
copy[0] = `${orig}\\${i}`;
2425
win32.resolve(...copy);
2526
} else {
2627
win32.resolve(...args);

lib/path.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ function normalizeString(path, allowAboveRoot, separator, isPathSeparator) {
9595
StringPrototypeCharCodeAt(res, res.length - 1) !== CHAR_DOT ||
9696
StringPrototypeCharCodeAt(res, res.length - 2) !== CHAR_DOT) {
9797
if (res.length > 2) {
98-
const lastSlashIndex = StringPrototypeLastIndexOf(res, separator);
98+
const lastSlashIndex = res.length - lastSegmentLength - 1;
9999
if (lastSlashIndex === -1) {
100100
res = '';
101101
lastSegmentLength = 0;
@@ -1171,6 +1171,12 @@ const posix = {
11711171
* @returns {string}
11721172
*/
11731173
resolve(...args) {
1174+
if (args.length === 0) {
1175+
const cwd = posixCwd();
1176+
if (StringPrototypeCharCodeAt(cwd, 0) === CHAR_FORWARD_SLASH) {
1177+
return cwd;
1178+
}
1179+
}
11741180
let resolvedPath = '';
11751181
let resolvedAbsolute = false;
11761182

0 commit comments

Comments
 (0)