Make syntax tree typing deeply readonly and reuse them in language server#868
Merged
nguerrera merged 6 commits intomicrosoft:mainfrom Aug 24, 2022
Merged
Conversation
nguerrera
commented
Aug 15, 2022
nguerrera
commented
Aug 15, 2022
|
You can try these changes at https://cadlplayground.z22.web.core.windows.net/prs/868/ |
0142f0e to
71c8640
Compare
nguerrera
commented
Aug 15, 2022
b36c320 to
b05fb59
Compare
4dc4d7b to
aa84bb1
Compare
timotheeguerin
approved these changes
Aug 23, 2022
| } | ||
| } | ||
|
|
||
| // (nicholg) Why do we have both compile and createProgram? |
Member
There was a problem hiding this comment.
todo? should we just remove compile?
Contributor
Author
There was a problem hiding this comment.
Yes, TODO. Didn't want to make a breaking change as part of this.
Contributor
Author
There was a problem hiding this comment.
I'll remove the comment and file an issue
| @@ -1,5 +1,6 @@ | |||
| import type { JSONSchemaType as AjvJSONSchemaType } from "ajv"; | |||
| import { Program } from "./program"; | |||
| import { JSONSchemaValidator } from "./schema-validator"; | |||
Member
There was a problem hiding this comment.
Suggested change
| import { JSONSchemaValidator } from "./schema-validator"; | |
| import { JSONSchemaValidator } from "./schema-validator.js"; |
Contributor
Author
There was a problem hiding this comment.
No longer applicable as we define it in types.ts instead of importing it.
nguerrera
commented
Aug 23, 2022
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
readonlyin their TS typing.Performance
I'm seeing approximately 2X less time spent in language server for typing the same sequence into petstore.cadl and navigating around with goto-definition, document-highlight:
I was hoping more than this. It turns out that we still lose a fair amount of time in I/O as the file system cache doesn't prevent us from hitting the disk walking directories, realpath'ing, and so on. We could go after that next. We currently have to process all of the imports before we can decide that a program is unchanged and that's where we incur this I/O. There's no reading of unchanged file content, but there is reading of unchanged directory structure.
Here is document-highlight cpu profile with a cache hit on the whole program. Almost all of the time is spent in realpath, stat, etc.:
I filed #894 to try to make the cache smarter to deal with this, but I don't think it's high priority. You will likely need a lot of files/imports to perceive it.
It also becomes apparent that parsing is already quite fast and the features that were only parsing and visiting the syntax tree for a single document (e.g. semantic-tokens, folding) didn't have much to gain for reasonably sized documents. The biggest win is on features like goto-definition, find-references, document-highlight that run on unchanged programs but need a full compilation.
Details
We used to inject symbols into symbol tables hanging off syntax trees to implement using statements including the implicit
using Cadland member references. To avoid this, we now do a copy-on-write to the symbol tables. This adds an extra map lookup for each call to resolveIdentifierInTable, where we first look for a copy of the table and then do the actual lookup. No noticeable slowdown was observed in profiling based on this. It does double the time in resolveIdentifierInTable as 1 lookup becomes two, but this does not make a significant difference overall and I think it's a worthwhile trade to get the reuse.createProgramgains a newoldProgramargument from which we will reuse syntax trees if the host gave us identicalSourceFileinstances. We will also reuse the entire oldProgram and skip checking if we find that the compiler options and source file set are unchanged. Language server keeps track of last compilation for a given entry point to provide oldProgram. Over time, it's possible that we can reuse more of oldProgram in more cases.CompilerHostgains a new optionalparseCachethat allows sharing syntax trees between programs even if oldProgram is not supplied or the oldProgram didn't have a particular source file. This is particularly useful for language server features that do not need an entire program but just the syntax tree of the current document. The language server also uses this.ParseOptions (currently include comments or not) can now be specified on
CompilerOptions. Language server uses this to always include comments so that features that need comments can share trees with features that don't.Fix #623
Fix https://github.com/Azure/cadl-azure/issues/619