Skip to content

Commit 96a40c3

Browse files
committed
sys: Use readdir withFileTypes option to skip lots of stat syscalls.
This makes walking large directory trees much more efficient. Signed-off-by: Anders Kaseorg <[email protected]>
1 parent f84fd30 commit 96a40c3

File tree

1 file changed

+19
-10
lines changed

1 file changed

+19
-10
lines changed

src/compiler/sys.ts

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1353,23 +1353,31 @@ namespace ts {
13531353
function getAccessibleFileSystemEntries(path: string): FileSystemEntries {
13541354
perfLogger.logEvent("ReadDir: " + (path || "."));
13551355
try {
1356-
const entries = _fs.readdirSync(path || ".").sort();
1356+
const entries = _fs.readdirSync(path || ".", { withFileTypes: true });
13571357
const files: string[] = [];
13581358
const directories: string[] = [];
1359-
for (const entry of entries) {
1359+
for (const dirent of entries) {
1360+
// withFileTypes is not supported before Node 10.10.
1361+
const entry = typeof dirent === "string" ? dirent : dirent.name;
1362+
13601363
// This is necessary because on some file system node fails to exclude
13611364
// "." and "..". See https://github.com/nodejs/node/issues/4002
13621365
if (entry === "." || entry === "..") {
13631366
continue;
13641367
}
1365-
const name = combinePaths(path, entry);
13661368

13671369
let stat: any;
1368-
try {
1369-
stat = _fs.statSync(name);
1370-
}
1371-
catch (e) {
1372-
continue;
1370+
if (typeof dirent === "string" || dirent.isSymbolicLink()) {
1371+
const name = combinePaths(path, entry);
1372+
1373+
try {
1374+
stat = _fs.statSync(name);
1375+
}
1376+
catch (e) {
1377+
continue;
1378+
}
1379+
} else {
1380+
stat = dirent;
13731381
}
13741382

13751383
if (stat.isFile()) {
@@ -1379,6 +1387,8 @@ namespace ts {
13791387
directories.push(entry);
13801388
}
13811389
}
1390+
files.sort();
1391+
directories.sort();
13821392
return { files, directories };
13831393
}
13841394
catch (e) {
@@ -1413,8 +1423,7 @@ namespace ts {
14131423
}
14141424

14151425
function getDirectories(path: string): string[] {
1416-
perfLogger.logEvent("ReadDir: " + path);
1417-
return filter<string>(_fs.readdirSync(path), dir => fileSystemEntryExists(combinePaths(path, dir), FileSystemEntryKind.Directory));
1426+
return getAccessibleFileSystemEntries(path).directories.slice();
14181427
}
14191428

14201429
function realpath(path: string): string {

0 commit comments

Comments
 (0)