Skip to content

Commit 2f8e7b3

Browse files
tracing: service uncached fs stats
1 parent e1c563f commit 2f8e7b3

File tree

3 files changed

+60
-3
lines changed

3 files changed

+60
-3
lines changed

README.md

+58-3
Original file line numberDiff line numberDiff line change
@@ -94,8 +94,8 @@ Comparing equivalent code paths:
9494

9595
> 📌 Filed on TypeScript as [⚡ Performance: Project service spends excess time cleaning client files when called synchronously](https://github.com/microsoft/TypeScript/issues/59335).
9696
97-
This trace shows the cost of the TypeScript project service calling `cleanupProjectsAndScriptInfos`.
98-
It also was run a common shape of linting: 1024 files with the "even" (triangle-shaped) imports layout.
97+
This comparison shows the cost of the TypeScript project service calling `cleanupProjectsAndScriptInfos`.
98+
It also was run on a common shape of linting: 1024 files with the "even" (triangle-shaped) imports layout.
9999

100100
See `traces/service-file-cleanup/`:
101101

@@ -107,7 +107,7 @@ They were generated with:
107107
```shell
108108
cd files-1024-layout-even-singlerun-true-types-service
109109
node --cpu-prof --cpu-prof-interval=100 --cpu-prof-name=baseline.cpuprofile ../../node_modules/eslint/bin/eslint.js
110-
# clear ../../node_modules/typescript/lib/js > cleanupProjectsAndScriptInfos
110+
# clear ../../node_modules/typescript/lib/typescript.js > cleanupProjectsAndScriptInfos
111111
node --cpu-prof --cpu-prof-interval=100 --cpu-prof-name=skipping.cpuprofile ../../node_modules/eslint/bin/eslint.js
112112
```
113113

@@ -118,6 +118,61 @@ Hyperfine measurements show a ~15-20% improvement in lint time:
118118
| Baseline | 3.215 s ± 0.041 s | 4.483 s |
119119
| Skipping | 2.501 s ± 0.017 s | 3.758 s |
120120

121+
### Comparison: Project Service Uncached File System Stats
122+
123+
This comparison shows the cost uncached `fs.statSync` calls inside the project service.
124+
It also was run on a common shape of linting: 1024 files with the "even" (triangle-shaped) imports layout.
125+
126+
See `traces/service-uncached-stats/`:
127+
128+
- `baseline.cpuprofile`: Baseline measurement with no changes
129+
- `caching.cpuprofile`: Adding a caching `Map` to TypeScript's `statSync`
130+
131+
They were generated with:
132+
133+
```shell
134+
cd files-1024-layout-even-singlerun-true-types-service
135+
node --cpu-prof --cpu-prof-interval=100 --cpu-prof-name=baseline.cpuprofile ../../node_modules/eslint/bin/eslint.js
136+
# edit ../../node_modules/typescript/lib/typescript.js > statSync (see diff below)
137+
node --cpu-prof --cpu-prof-interval=100 --cpu-prof-name=caching.cpuprofile ../../node_modules/eslint/bin/eslint.js
138+
```
139+
140+
<details>
141+
<summary><code>diff</code> patch to switch to the <em>Caching</em> variant...</summary>
142+
143+
```diff
144+
diff --git a/node_modules/typescript/lib/typescript.js b/node_modules/typescript/lib/typescript.js
145+
index 4baad59..44639d5 100644
146+
--- a/node_modules/typescript/lib/typescript.js
147+
+++ b/node_modules/typescript/lib/typescript.js
148+
@@ -8546,9 +8546,15 @@ var sys = (() => {
149+
}
150+
}
151+
};
152+
+ const statCache = new Map();
153+
return nodeSystem;
154+
function statSync(path) {
155+
- return _fs.statSync(path, { throwIfNoEntry: false });
156+
+ if (statCache.has(path)) {
157+
+ return statCache.get(path);
158+
+ }
159+
+ const result = _fs.statSync(path, { throwIfNoEntry: false });
160+
+ statCache.set(path, result);
161+
+ return result;
162+
}
163+
function enableCPUProfiler(path, cb) {
164+
if (activeSession) {
165+
```
166+
167+
</details>
168+
169+
Hyperfine measurements show a ~7-12% improvement in lint time:
170+
171+
| Variant | Measurement | User Time |
172+
| -------- | ----------------- | --------- |
173+
| Baseline | 3.112 s ± 0.033 s | 4.382 |
174+
| Caching | 2.740 s ± 0.030 s | 4.032 |
175+
121176
## Contributors
122177

123178
<!-- spellchecker: disable -->

traces/service-uncached-stats/baseline.cpuprofile

+1
Large diffs are not rendered by default.

traces/service-uncached-stats/caching.cpuprofile

+1
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)