Skip to content

Commit 64704a1

Browse files
anderskamcasey
authored andcommitted
sys: Use readdir withFileTypes option to skip lots of stat syscalls (#35286)
This makes walking large directory trees much more efficient on Node 10.10 or later. See: https://lwn.net/Articles/606995/ https://www.python.org/dev/peps/pep-0471/ nodejs/node#22020 https://nodejs.org/en/blog/release/v10.10.0/ Signed-off-by: Anders Kaseorg <[email protected]>
1 parent 1dafd09 commit 64704a1

File tree

1 file changed

+19
-9
lines changed

1 file changed

+19
-9
lines changed

src/compiler/sys.ts

+19-9
Original file line numberDiff line numberDiff line change
@@ -1617,23 +1617,32 @@ namespace ts {
16171617
function getAccessibleFileSystemEntries(path: string): FileSystemEntries {
16181618
perfLogger.logEvent("ReadDir: " + (path || "."));
16191619
try {
1620-
const entries = _fs.readdirSync(path || ".").sort();
1620+
const entries = _fs.readdirSync(path || ".", { withFileTypes: true });
16211621
const files: string[] = [];
16221622
const directories: string[] = [];
1623-
for (const entry of entries) {
1623+
for (const dirent of entries) {
1624+
// withFileTypes is not supported before Node 10.10.
1625+
const entry = typeof dirent === "string" ? dirent : dirent.name;
1626+
16241627
// This is necessary because on some file system node fails to exclude
16251628
// "." and "..". See https://github.com/nodejs/node/issues/4002
16261629
if (entry === "." || entry === "..") {
16271630
continue;
16281631
}
1629-
const name = combinePaths(path, entry);
16301632

16311633
let stat: any;
1632-
try {
1633-
stat = _fs.statSync(name);
1634+
if (typeof dirent === "string" || dirent.isSymbolicLink()) {
1635+
const name = combinePaths(path, entry);
1636+
1637+
try {
1638+
stat = _fs.statSync(name);
1639+
}
1640+
catch (e) {
1641+
continue;
1642+
}
16341643
}
1635-
catch (e) {
1636-
continue;
1644+
else {
1645+
stat = dirent;
16371646
}
16381647

16391648
if (stat.isFile()) {
@@ -1643,6 +1652,8 @@ namespace ts {
16431652
directories.push(entry);
16441653
}
16451654
}
1655+
files.sort();
1656+
directories.sort();
16461657
return { files, directories };
16471658
}
16481659
catch (e) {
@@ -1677,8 +1688,7 @@ namespace ts {
16771688
}
16781689

16791690
function getDirectories(path: string): string[] {
1680-
perfLogger.logEvent("ReadDir: " + path);
1681-
return filter<string>(_fs.readdirSync(path), dir => fileSystemEntryExists(combinePaths(path, dir), FileSystemEntryKind.Directory));
1691+
return getAccessibleFileSystemEntries(path).directories.slice();
16821692
}
16831693

16841694
function realpath(path: string): string {

0 commit comments

Comments
 (0)