microsoft / vscode

Visual Studio Code
https://code.visualstudio.com
MIT License
163.52k stars 28.99k forks source link

Compiling VSCode project substantially faster with Status Bar and Panel hidden #160118

Open 0x00C5 opened 2 years ago

0x00C5 commented 2 years ago

(edited to add both the STATUS BAR and PANEL must be hidden for speed increase)

I recently noticed that my project builds substantially faster with the Panel and Status Bar hidden. I hid the Panel the other day and noticed a huge performance increase. I pretty much use default tsconfig.json configuration. Wondering if anyone else can recreate?

Timing with panel open: 19.86s Timing with panel closed: 4.60s

It appears the Parse Time, Bind Time and Check Time are much faster with Panel and Status Bar closed.

The steps I use to build:

tasks.json

{
"version": "2.0.0",
"tasks": [
  {
    "label": "Build Project",
    "type": "shell",
    "group": "build",
    "problemMatcher": ["$tsc"],
    "command": [
      "tsc -b --extendedDiagnostics project/tsconfig.json"
    ]
  ]
}

Output of --extendedDiagnostics with Panel open (edited same file to recreate build):

Files:                         158
Lines of Library:            27205
Lines of Definitions:        37867
Lines of TypeScript:         21539
Lines of JavaScript:             0
Lines of JSON:                   0
Lines of Other:                  0
Nodes of Library:           118033
Nodes of Definitions:        94131
Nodes of TypeScript:         61644
Nodes of JavaScript:             0
Nodes of JSON:                   0
Nodes of Other:                  0
Identifiers:                 96568
Symbols:                     66162
Types:                        9508
Instantiations:               4692
Memory used:               118831K
Assignability cache size:     1584
Identity cache size:            59
Subtype cache size:            109
Strict subtype cache size:     350
I/O Read time:               0.10s
Parse time:                  5.02s          <<
ResolveModule time:          0.30s          <<
ResolveTypeReference time:   0.04s          <<
Program time:                5.97s          <<
Bind time:                   2.38s          <<
Check time:                 11.32s          <<
transformTime time:          1.19s          <<
commentTime time:            0.00s
printTime time:              0.19s
Emit time:                   0.19s
Source Map time:             0.01s
I/O Write time:              0.00s
Total time:                 19.86s 

When Panel closed:

Files:                         158
Lines of Library:            27205
Lines of Definitions:        37867
Lines of TypeScript:         21539
Lines of JavaScript:             0
Lines of JSON:                   0
Lines of Other:                  0
Nodes of Library:           118033
Nodes of Definitions:        94131
Nodes of TypeScript:         61644
Nodes of JavaScript:             0
Nodes of JSON:                   0
Nodes of Other:                  0
Identifiers:                 96568
Symbols:                     66162
Types:                        9508
Instantiations:               4692
Memory used:               132751K
Assignability cache size:     1584
Identity cache size:            59
Subtype cache size:            109
Strict subtype cache size:     350
I/O Read time:               0.02s
Parse time:                  1.34s          <<
ResolveModule time:          0.06s          <<
ResolveTypeReference time:   0.01s          <<
Program time:                1.55s          <<
Bind time:                   0.74s          <<
Check time:                  2.27s          <<
transformTime time:          0.20s          <<
commentTime time:            0.00s
printTime time:              0.04s
Emit time:                   0.04s
Source Map time:             0.00s
I/O Write time:              0.00s
Total time:                  4.60s 
0x00C5 commented 2 years ago

Couple notes:

  1. Nothing is output to the console/terminal in Panel during the build
  2. I'm on fedora linux
  3. I don't have any extensions installed
meganrogge commented 2 years ago

does changing terminal.integrated.gpuAcceleration impact the performance?

0x00C5 commented 2 years ago

With panel open (edited same file each run):

terminal.integrated.gpuAcceleration: "off"      Total time: 21.64s
terminal.integrated.gpuAcceleration: "on"       Total time: 16.52s

With panel closed:

terminal.integrated.gpuAcceleration: "off"      Total time: 5.29s
terminal.integrated.gpuAcceleration: "on"       Total time: 5.12s

The only thing printed to Terminal until build completed is:

Executing task in folder project: tsc -b --extendedDiagnostics project/tsconfig.json

meganrogge commented 2 years ago

Thanks for investigating and for all of the info.

What's interesting to me is that the data gets parsed regardless of the panel's visibility and yet that parsing step is ~3.7 seconds slower on your machine. I see a bunch of resize events happen when I have the panel open.

Seems like we need to find out which other actions are counted in that Parsing step.

https://user-images.githubusercontent.com/29464607/191798833-7da633a5-8e89-4b87-8d79-a52841e81e5d.mov

meganrogge commented 2 years ago

on mac, I can't see a noticeable slowdown

meganrogge commented 2 years ago

/duplicate #155134

vscodenpa commented 2 years ago

Thanks for creating this issue! We figured it's covering the same as another one we already have. Thus, we closed this one as a duplicate. You can search for similar existing issues. See also our issue reporting guidelines.

Happy Coding!

Tyriar commented 2 years ago

Actually let's track the OOM crash in #155134 and the command duration here.

Tyriar commented 2 years ago

This is actually as designed, what's happening here is both data parsing and rendering is on the same main thread, data parsing consumes as much time as will fit in ~16ms before triggering an animation frame. The animation frame then performs the render which also runs on the main thread and takes time away from the parsing.

It's a little unclear what's most correct here but how it is currently is the renderer is optimized for high FPS, smoothness and responsiveness. We could for example cap the FPS rate when the terminal is getting flooded like this which would increase parsing speed, but then people would complain about the opposite of FPS drops.

Another idea we've tossed around is running the parser (or renderer?) in a different thread which is probably more work than it's worth tbh.

Let's move this discussion to https://github.com/xtermjs/xterm.js/issues/4135

0x00C5 commented 2 years ago

I appreciate you looking into it. I'm not sure if I misunderstand you but nothing is output to the terminal during build which is why I filed the bug.

To better demonstrate the problem, here's some code that generates a file with 48,000 lines of typescript to compile. It does not emit anything to console:

var fs = require("fs");

var buf = [];
for (var i = 0, L = 10_000; i < L; i++) {
  buf.push(`
interface t_${i} {
  a: number
  b: number
}

function x_${i} (x: t_${i}): number {
  return x.a + x.b;
}

x_${i}({a:1, b:2});
`);
}

fs.writeFileSync("/tmp/panel.ts", buf.join("\n"), "utf8");

Here's the tsconfig.json used to build the file:

{
  "files": [
    "./src/panel.ts"
  ],
  "compilerOptions": {
    "moduleResolution": "node",
    "module": "commonjs",
    "outDir": "./build",
    "rootDir": "."
  }
}

Building it with panel open:

 *  Executing task in folder projects: tsc -b --extendedDiagnostics panel/tsconfig.json 

Files:                         109
Lines of Library:             8880
Lines of Definitions:        40054
Lines of TypeScript:         48000
Lines of JavaScript:             0
Lines of JSON:                   0
Lines of Other:                  0
Nodes of Library:            23429
Nodes of Definitions:        99929
Nodes of TypeScript:        144002
Nodes of JavaScript:             0
Nodes of JSON:                   0
Nodes of Other:                  0
Identifiers:                 98530
Symbols:                     87477
Types:                       31448
Instantiations:              12843
Memory used:               144697K              <<
Assignability cache size:    10190
Identity cache size:           100
Subtype cache size:              0
Strict subtype cache size:       0
I/O Read time:               0.04s
Parse time:                  2.90s
ResolveTypeReference time:   0.07s
ResolveModule time:          0.13s
Program time:                3.44s
Bind time:                   1.59s
Check time:                 19.30s              <<
transformTime time:          1.42s
commentTime time:            0.53s
printTime time:              6.01s
Emit time:                   6.02s
I/O Write time:              0.03s
Total time:                 30.35s
 *  Terminal will be reused by tasks, press any key to close it. 

Building it with panel closed:

 *  Executing task in folder projects: tsc -b --extendedDiagnostics panel/tsconfig.json 

Files:                         109
Lines of Library:             8880
Lines of Definitions:        40054
Lines of TypeScript:         48000
Lines of JavaScript:             0
Lines of JSON:                   0
Lines of Other:                  0
Nodes of Library:            23429
Nodes of Definitions:        99929
Nodes of TypeScript:        144002
Nodes of JavaScript:             0
Nodes of JSON:                   0
Nodes of Other:                  0
Identifiers:                 98530
Symbols:                     87477
Types:                       31448
Instantiations:              12843
Memory used:               144507K              <<
Assignability cache size:    10190
Identity cache size:           100
Subtype cache size:              0
Strict subtype cache size:       0
I/O Read time:               0.02s
Parse time:                  1.24s
ResolveTypeReference time:   0.02s
ResolveModule time:          0.04s
Program time:                1.45s
Bind time:                   0.59s
Check time:                  3.56s              <<
transformTime time:          0.19s
commentTime time:            0.15s
printTime time:              1.29s
Emit time:                   1.30s
I/O Write time:              0.01s
Total time:                  6.90s
 *  Terminal will be reused by tasks, press any key to close it. 

Note the memory usage is the same (it's not OOM). There's no buffer to flush to the console so it shouldn't be animation frame / rendering issue unless it doesn't return immediately when there's nothing to do.

And "Check time" takes majority of time when the panel is open (19.30s vs 3.56s when closed).

0x00C5 commented 2 years ago

NOTE: I edited the source file between builds

Tyriar commented 2 years ago

Reopening as there's no output as @0x00C5 mentioned so https://github.com/xtermjs/xterm.js/issues/4135 wouldn't fix.

0x00C5 commented 2 years ago

I ran the performance profiler during the build. It appears the terminal isn't ignoring the empty buffer and instead is resizing/reflowing the terminal as if it's being flooded with data. I'm not familiar with how it works internally but it appears it's running the entire routine even if there's nothing in the output buffer.

meganrogge commented 2 years ago

thanks for the info.

let us know if it's not fixed in insider's today

/duplicate #161758

vscodenpa commented 2 years ago

Thanks for creating this issue! We figured it's covering the same as another one we already have. Thus, we closed this one as a duplicate. You can search for similar existing issues. See also our issue reporting guidelines.

Happy Coding!

0x00C5 commented 2 years ago

Doesn't appear to be fixed.

The build time in code-insider is 31.83s (panel open) and 15.80s (panel closed).

Version: 1.72.0-insider
Commit: 36b1398cfbabbe91d695717d76b818a788f7b7d9
Date: 2022-09-27T05:19:13.510Z
Electron: 19.0.17
Chromium: 102.0.5005.167
Node.js: 16.14.2
V8: 10.2.154.15-electron.0
OS: Linux x64 5.19.8-200.fc36.x86_64
Sandboxed: Yes
meganrogge commented 2 years ago

Yeah I actually realized this is not related to that issue at all because there is no output

0x00C5 commented 2 years ago

So I ran two performance profiles running on code-insiders. One with panel open and other with panel closed. Hope they help

Profile-20220927T120823-panel-open.json.txt took 29.14s

Profile-20220927T121903-panel-closed.json.txt took 18.71s

Tyriar commented 2 years ago

Hmm I don't see much terminal related calls in the panel open profile but quite a bit of menu/view pane related stuff. I wonder if this also happens when you run something but open up a different view (output?) in the panel.

0x00C5 commented 2 years ago

The timing is no different when OUTPUT tab focused during build

Profile-20220927T155221-panel-open-output-tab.json.txt

0x00C5 commented 1 year ago

Hi, little update: today I realized you must hide both the status bar and the Panel for the significant compile time speed up.

hmottestad commented 9 months ago

Any chance that anyone is looking into this?

r3m0t commented 9 months ago

Could the issue be in typescript itself? It sounds like it's sending terminal control messages to the terminal. Maybe this takes a different amount of time if Status Bar and Panel are closed. As it's not emitting any diagnostics this should only happen once, it shouldn't take 15 seconds!

In top, is the CPU usage in VSCode, tsc or both?

0x00C5 commented 9 months ago

To recreate, you must hide the two items highlighted below for compilation speed increase:

image1

Both of these must be hidden or you will not be able to recreate (@meganrogge video shows the STATUS BAR open when when failing to reproduce the speed increase).

A couple months ago I had the status bar open and builds were slow again. It was then I realized that both must be hidden to reproduce so I updated the bug report.

0x00C5 commented 9 months ago

Could the issue be in typescript itself? It sounds like it's sending terminal control messages to the terminal. Maybe this takes a different amount of time if Status Bar and Panel are closed.

It's likely in how status messages are being handled as both panels show an animation when a project is compiling