microsoft / TypeScript

TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
https://www.typescriptlang.org
Apache License 2.0
101.28k stars 12.52k forks source link

`UpdateProjectIfDirty` is slow on large projects #60633

Open dbaeumer opened 3 days ago

dbaeumer commented 3 days ago

🔎 Search Terms

UpdateProjectIfDirty language server slow

🕗 Version & Regression Information

⏯ Playground Link

No response

💻 Code

Steps to reproduce:

Observe: updateGraphWorker takes roughly 300ms on my machine

I took a performance trace and a lot of time is spent in GC and getNormalizedAbsolutePath. I added a simply unbound cache to the method like

const pathCache = new Map();
function getNormalizedAbsolutePath(fileName, currentDirectory) {
  let cache = pathCache.get(currentDirectory);
  if (cache === undefined) {
    cache = new Map();
    pathCache.set(currentDirectory, cache);
  }
  let normalized = cache.get(fileName);
  if (normalized === undefined) {
    normalized = getPathFromPathComponents(getNormalizedPathComponents(fileName, currentDirectory));
    cache.set(fileName, normalized);
  }
  return normalized;
}

which cuts the time for updateGraphWorker in half. However there are still some GCs going on and a lot of time is now spent in verifyCompilerOptions / getNormalizedPathComponents.

🙁 Actual behavior

Takes 300ms to update on key stroke

🙂 Expected behavior

Adding a new line should be even in large project only cost a couple of ms :-)

Additional information about the issue

No response

dbaeumer commented 2 days ago

Doing a comparable cache in getNormalizedPathComponents brings the time down to 75ms.

vscode-profile-2024-11-28-09-36-24.cpuprofile vscode-profile-2024-11-28-12-42-42.cpuprofile vscode-profile-2024-11-28-15-29-10.cpuprofile

Here are also some of the CPU profiles I captured.