Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Switch to ES Map/Set internally #33771

Merged
merged 15 commits into from
Jun 26, 2020
Merged

Switch to ES Map/Set internally #33771

merged 15 commits into from
Jun 26, 2020

Conversation

rbuckton
Copy link
Member

@rbuckton rbuckton commented Oct 2, 2019

Currently leaving this as a Draft PR for discussion. This improves our Map shim to support non-string keys, and adds a shim for Set so that we might consider using it in the compiler as well.

These shims exist for a vanishingly rare corner case of TypeScript running in an environment without native implementations (at this point, primarily just IE).

@rbuckton rbuckton force-pushed the esMapSetShim branch 3 times, most recently from e4769a2 to 374ce8b Compare October 7, 2019 20:49
@rbuckton rbuckton changed the title ES Map/Set/WeakMap/WeakSet shims Switch to ES Map/Set/WeakMap/WeakSet internally Jun 18, 2020
@rbuckton rbuckton changed the title Switch to ES Map/Set/WeakMap/WeakSet internally Switch to ES Map/Set internally Jun 19, 2020
@rbuckton rbuckton marked this pull request as ready for review June 19, 2020 06:44
@rbuckton
Copy link
Member Author

@typescript-bot perf test
@typescript-bot run dt
@typescript-bot test this
@typescript-bot user test this

@typescript-bot
Copy link
Collaborator

typescript-bot commented Jun 19, 2020

Heya @rbuckton, I've started to run the parallelized community code test suite on this PR at 79eb8ee. You can monitor the build here.

@typescript-bot
Copy link
Collaborator

typescript-bot commented Jun 19, 2020

Heya @rbuckton, I've started to run the extended test suite on this PR at 79eb8ee. You can monitor the build here.

@typescript-bot
Copy link
Collaborator

typescript-bot commented Jun 19, 2020

Heya @rbuckton, I've started to run the parallelized Definitely Typed test suite on this PR at 79eb8ee. You can monitor the build here.

@typescript-bot
Copy link
Collaborator

typescript-bot commented Jun 19, 2020

Heya @rbuckton, I've started to run the perf test suite on this PR at 79eb8ee. You can monitor the build here.

Update: The results are in!

@typescript-bot
Copy link
Collaborator

@rbuckton
The results of the perf run you requested are in!

Here they are:

Comparison Report - master..33771

Metric master 33771 Delta Best Worst
Angular - node (v10.16.3, x64)
Memory used 340,339k (± 0.01%) 339,863k (± 0.02%) -475k (- 0.14%) 339,715k 340,021k
Parse Time 1.99s (± 0.85%) 1.99s (± 0.55%) -0.00s (- 0.25%) 1.97s 2.01s
Bind Time 0.80s (± 0.65%) 0.80s (± 0.72%) -0.00s (- 0.12%) 0.79s 0.81s
Check Time 4.73s (± 0.57%) 4.70s (± 0.31%) -0.03s (- 0.57%) 4.67s 4.74s
Emit Time 5.22s (± 0.80%) 5.15s (± 0.61%) -0.07s (- 1.36%) 5.08s 5.22s
Total Time 12.74s (± 0.45%) 12.64s (± 0.31%) -0.10s (- 0.78%) 12.54s 12.69s
Monaco - node (v10.16.3, x64)
Memory used 338,915k (± 0.02%) 338,981k (± 0.02%) +66k (+ 0.02%) 338,848k 339,169k
Parse Time 1.58s (± 0.41%) 1.58s (± 0.60%) -0.00s (- 0.32%) 1.56s 1.61s
Bind Time 0.70s (± 0.83%) 0.70s (± 1.04%) +0.00s (+ 0.14%) 0.68s 0.71s
Check Time 4.86s (± 0.44%) 4.86s (± 0.65%) +0.00s (+ 0.02%) 4.78s 4.93s
Emit Time 2.75s (± 0.94%) 2.75s (± 1.00%) +0.00s (+ 0.00%) 2.69s 2.82s
Total Time 9.89s (± 0.46%) 9.88s (± 0.45%) -0.01s (- 0.07%) 9.81s 9.98s
TFS - node (v10.16.3, x64)
Memory used 301,939k (± 0.08%) 301,897k (± 0.02%) -42k (- 0.01%) 301,785k 302,051k
Parse Time 1.21s (± 0.84%) 1.21s (± 0.63%) -0.00s (- 0.41%) 1.18s 1.22s
Bind Time 0.66s (± 0.76%) 0.65s (± 0.89%) -0.01s (- 0.76%) 0.63s 0.66s
Check Time 4.37s (± 0.69%) 4.36s (± 0.34%) -0.01s (- 0.21%) 4.32s 4.39s
Emit Time 2.89s (± 0.99%) 2.90s (± 0.79%) +0.00s (+ 0.17%) 2.86s 2.97s
Total Time 9.12s (± 0.64%) 9.12s (± 0.39%) -0.01s (- 0.09%) 9.03s 9.21s
material-ui - node (v10.16.3, x64)
Memory used 459,485k (± 0.01%) 459,320k (± 0.01%) -165k (- 0.04%) 459,216k 459,494k
Parse Time 2.05s (± 0.53%) 2.05s (± 0.47%) -0.00s (- 0.15%) 2.03s 2.07s
Bind Time 0.66s (± 1.63%) 0.65s (± 1.28%) -0.01s (- 1.97%) 0.63s 0.67s
Check Time 12.81s (± 0.67%) 12.88s (± 0.99%) +0.07s (+ 0.52%) 12.66s 13.20s
Emit Time 0.00s (± 0.00%) 0.00s (± 0.00%) 0.00s ( NaN%) 0.00s 0.00s
Total Time 15.52s (± 0.54%) 15.58s (± 0.83%) +0.06s (+ 0.37%) 15.34s 15.87s
Angular - node (v12.1.0, x64)
Memory used 317,771k (± 0.02%) 317,337k (± 0.01%) -434k (- 0.14%) 317,253k 317,400k
Parse Time 1.97s (± 0.67%) 1.95s (± 1.07%) -0.02s (- 0.86%) 1.91s 1.99s
Bind Time 0.78s (± 0.79%) 0.78s (± 0.83%) -0.00s (- 0.13%) 0.77s 0.79s
Check Time 4.58s (± 0.61%) 4.58s (± 0.42%) -0.00s (- 0.09%) 4.53s 4.62s
Emit Time 5.34s (± 0.99%) 5.38s (± 1.28%) +0.04s (+ 0.71%) 5.25s 5.54s
Total Time 12.67s (± 0.64%) 12.68s (± 0.76%) +0.01s (+ 0.09%) 12.50s 12.95s
Monaco - node (v12.1.0, x64)
Memory used 321,471k (± 0.02%) 321,455k (± 0.02%) -16k (- 0.01%) 321,349k 321,576k
Parse Time 1.54s (± 0.91%) 1.53s (± 0.58%) -0.01s (- 0.58%) 1.51s 1.55s
Bind Time 0.67s (± 0.71%) 0.67s (± 0.77%) -0.00s (- 0.30%) 0.66s 0.68s
Check Time 4.65s (± 0.59%) 4.65s (± 0.51%) +0.00s (+ 0.04%) 4.60s 4.70s
Emit Time 2.79s (± 0.73%) 2.81s (± 0.82%) +0.02s (+ 0.72%) 2.77s 2.87s
Total Time 9.66s (± 0.53%) 9.67s (± 0.36%) +0.01s (+ 0.16%) 9.57s 9.75s
TFS - node (v12.1.0, x64)
Memory used 286,358k (± 0.02%) 286,360k (± 0.03%) +2k (+ 0.00%) 286,261k 286,697k
Parse Time 1.23s (± 0.77%) 1.22s (± 0.54%) -0.01s (- 1.13%) 1.21s 1.24s
Bind Time 0.62s (± 1.42%) 0.62s (± 1.20%) -0.00s (- 0.48%) 0.60s 0.64s
Check Time 4.28s (± 0.60%) 4.26s (± 0.31%) -0.02s (- 0.40%) 4.23s 4.28s
Emit Time 2.95s (± 1.63%) 2.91s (± 0.97%) -0.04s (- 1.25%) 2.87s 2.99s
Total Time 9.08s (± 0.54%) 9.01s (± 0.33%) -0.07s (- 0.74%) 8.94s 9.09s
material-ui - node (v12.1.0, x64)
Memory used 437,853k (± 0.06%) 437,446k (± 0.09%) -407k (- 0.09%) 436,451k 437,807k
Parse Time 2.03s (± 0.69%) 2.01s (± 0.68%) -0.02s (- 0.79%) 1.99s 2.05s
Bind Time 0.64s (± 0.70%) 0.63s (± 1.16%) -0.01s (- 1.57%) 0.62s 0.65s
Check Time 11.58s (± 1.08%) 11.61s (± 1.26%) +0.03s (+ 0.24%) 11.33s 12.00s
Emit Time 0.00s (± 0.00%) 0.00s (± 0.00%) 0.00s ( NaN%) 0.00s 0.00s
Total Time 14.26s (± 0.94%) 14.25s (± 1.06%) -0.00s (- 0.01%) 13.97s 14.66s
Angular - node (v8.9.0, x64)
Memory used 336,820k (± 0.02%) 336,482k (± 0.01%) -339k (- 0.10%) 336,339k 336,547k
Parse Time 2.49s (± 0.40%) 2.49s (± 0.46%) -0.00s (- 0.04%) 2.46s 2.51s
Bind Time 0.83s (± 0.96%) 0.83s (± 0.69%) -0.00s (- 0.24%) 0.82s 0.84s
Check Time 5.31s (± 0.54%) 5.34s (± 0.51%) +0.04s (+ 0.66%) 5.26s 5.39s
Emit Time 5.84s (± 1.65%) 5.93s (± 1.01%) +0.09s (+ 1.47%) 5.85s 6.13s
Total Time 14.48s (± 0.71%) 14.60s (± 0.40%) +0.12s (+ 0.80%) 14.50s 14.77s
Monaco - node (v8.9.0, x64)
Memory used 340,275k (± 0.02%) 340,274k (± 0.01%) -1k (- 0.00%) 340,177k 340,389k
Parse Time 1.86s (± 0.43%) 1.87s (± 0.64%) +0.01s (+ 0.32%) 1.85s 1.91s
Bind Time 0.87s (± 0.57%) 0.86s (± 0.79%) -0.00s (- 0.23%) 0.85s 0.88s
Check Time 5.34s (± 0.63%) 5.35s (± 0.46%) +0.00s (+ 0.09%) 5.28s 5.40s
Emit Time 3.23s (± 0.71%) 3.21s (± 0.36%) -0.02s (- 0.56%) 3.18s 3.23s
Total Time 11.30s (± 0.43%) 11.29s (± 0.32%) -0.01s (- 0.09%) 11.23s 11.37s
TFS - node (v8.9.0, x64)
Memory used 303,635k (± 0.02%) 303,624k (± 0.02%) -11k (- 0.00%) 303,531k 303,721k
Parse Time 1.54s (± 0.84%) 1.54s (± 0.54%) +0.01s (+ 0.59%) 1.53s 1.56s
Bind Time 0.65s (± 0.85%) 0.65s (± 0.80%) -0.00s (- 0.15%) 0.64s 0.66s
Check Time 5.00s (± 1.74%) 4.93s (± 1.55%) -0.07s (- 1.38%) 4.83s 5.11s
Emit Time 3.04s (± 2.55%) 3.10s (± 3.19%) +0.05s (+ 1.77%) 2.84s 3.23s
Total Time 10.24s (± 0.33%) 10.23s (± 0.52%) -0.01s (- 0.10%) 10.08s 10.36s
material-ui - node (v8.9.0, x64)
Memory used 463,634k (± 0.01%) 463,383k (± 0.01%) -251k (- 0.05%) 463,291k 463,450k
Parse Time 2.39s (± 0.60%) 2.37s (± 0.49%) -0.02s (- 0.67%) 2.35s 2.40s
Bind Time 0.77s (± 1.52%) 0.77s (± 1.30%) -0.00s (- 0.52%) 0.75s 0.80s
Check Time 17.12s (± 1.31%) 16.91s (± 1.14%) -0.21s (- 1.20%) 16.42s 17.20s
Emit Time 0.00s (± 0.00%) 0.00s (±222.80%) 🔻+0.00s (+ ∞%) 0.00s 0.01s
Total Time 20.28s (± 1.19%) 20.05s (± 0.98%) -0.23s (- 1.11%) 19.57s 20.36s
Angular - node (v8.9.0, x86)
Memory used 193,337k (± 0.02%) 193,172k (± 0.02%) -165k (- 0.09%) 193,074k 193,281k
Parse Time 2.45s (± 0.96%) 2.42s (± 0.85%) -0.03s (- 1.10%) 2.38s 2.48s
Bind Time 0.98s (± 0.97%) 0.97s (± 0.77%) -0.01s (- 0.92%) 0.95s 0.98s
Check Time 4.80s (± 0.57%) 4.79s (± 0.63%) -0.01s (- 0.23%) 4.73s 4.85s
Emit Time 5.97s (± 1.22%) 5.92s (± 1.25%) -0.05s (- 0.92%) 5.70s 6.09s
Total Time 14.20s (± 0.74%) 14.10s (± 0.68%) -0.10s (- 0.74%) 13.83s 14.32s
Monaco - node (v8.9.0, x86)
Memory used 193,279k (± 0.03%) 193,295k (± 0.01%) +16k (+ 0.01%) 193,241k 193,346k
Parse Time 1.90s (± 0.63%) 1.90s (± 0.82%) -0.00s (- 0.05%) 1.87s 1.94s
Bind Time 0.68s (± 0.87%) 0.68s (± 0.70%) -0.00s (- 0.15%) 0.67s 0.69s
Check Time 5.44s (± 0.40%) 5.44s (± 0.47%) -0.00s (- 0.02%) 5.39s 5.50s
Emit Time 2.67s (± 0.87%) 2.67s (± 0.69%) -0.00s (- 0.11%) 2.64s 2.73s
Total Time 10.70s (± 0.43%) 10.69s (± 0.42%) -0.00s (- 0.05%) 10.61s 10.81s
TFS - node (v8.9.0, x86)
Memory used 173,586k (± 0.03%) 173,598k (± 0.02%) +12k (+ 0.01%) 173,516k 173,659k
Parse Time 1.58s (± 0.72%) 1.57s (± 0.57%) -0.00s (- 0.25%) 1.56s 1.60s
Bind Time 0.62s (± 0.55%) 0.63s (± 1.59%) +0.01s (+ 1.62%) 0.61s 0.66s
Check Time 4.66s (± 0.53%) 4.65s (± 1.04%) -0.01s (- 0.15%) 4.55s 4.77s
Emit Time 2.81s (± 1.91%) 2.80s (± 1.57%) -0.02s (- 0.53%) 2.70s 2.90s
Total Time 9.66s (± 0.60%) 9.65s (± 0.82%) -0.02s (- 0.17%) 9.49s 9.84s
material-ui - node (v8.9.0, x86)
Memory used 262,444k (± 0.02%) 262,304k (± 0.02%) -140k (- 0.05%) 262,208k 262,415k
Parse Time 2.44s (± 0.70%) 2.45s (± 0.73%) +0.00s (+ 0.04%) 2.41s 2.49s
Bind Time 0.67s (± 1.59%) 0.66s (± 1.40%) -0.00s (- 0.60%) 0.65s 0.69s
Check Time 15.55s (± 0.49%) 15.48s (± 0.70%) -0.07s (- 0.44%) 15.30s 15.81s
Emit Time 0.00s (± 0.00%) 0.00s (± 0.00%) 0.00s ( NaN%) 0.00s 0.00s
Total Time 18.67s (± 0.43%) 18.60s (± 0.52%) -0.07s (- 0.37%) 18.44s 18.88s
System
Machine Namets-ci-ubuntu
Platformlinux 4.4.0-166-generic
Architecturex64
Available Memory16 GB
Available Memory1 GB
CPUs4 × Intel(R) Core(TM) i7-4770 CPU @ 3.40GHz
Hosts
  • node (v10.16.3, x64)
  • node (v12.1.0, x64)
  • node (v8.9.0, x64)
  • node (v8.9.0, x86)
Scenarios
  • Angular - node (v10.16.3, x64)
  • Angular - node (v12.1.0, x64)
  • Angular - node (v8.9.0, x64)
  • Angular - node (v8.9.0, x86)
  • Monaco - node (v10.16.3, x64)
  • Monaco - node (v12.1.0, x64)
  • Monaco - node (v8.9.0, x64)
  • Monaco - node (v8.9.0, x86)
  • TFS - node (v10.16.3, x64)
  • TFS - node (v12.1.0, x64)
  • TFS - node (v8.9.0, x64)
  • TFS - node (v8.9.0, x86)
  • material-ui - node (v10.16.3, x64)
  • material-ui - node (v12.1.0, x64)
  • material-ui - node (v8.9.0, x64)
  • material-ui - node (v8.9.0, x86)
Benchmark Name Iterations
Current 33771 10
Baseline master 10

# Conflicts:
#	src/services/refactors/extractSymbol.ts
src/compiler/builderState.ts Outdated Show resolved Hide resolved
@@ -3204,7 +3204,7 @@ namespace ts {
// If the emit is enabled make sure that every output file is unique and not overwriting any of the input files
if (!options.noEmit && !options.suppressOutputPathCheck) {
const emitHost = getEmitHost();
const emitFilesSeen = createMap<true>();
const emitFilesSeen = new Set<string>();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Key as path

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This breaks verifyEmitFilePath unless we cast the key to Path.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

emitFilesSeen.add(emitFileKey); is path in there though.

src/compiler/program.ts Outdated Show resolved Hide resolved
src/compiler/resolutionCache.ts Outdated Show resolved Hide resolved
src/compiler/resolutionCache.ts Outdated Show resolved Hide resolved
src/server/session.ts Outdated Show resolved Hide resolved
src/services/documentRegistry.ts Outdated Show resolved Hide resolved
src/services/documentRegistry.ts Outdated Show resolved Hide resolved
src/services/services.ts Outdated Show resolved Hide resolved
src/shims/collectionShims.ts Outdated Show resolved Hide resolved
@rbuckton
Copy link
Member Author

@sheetalkamat: I've made most of the suggested key changes, but there are some that would result in type errors that I do not have enough context to resolve.

@rbuckton
Copy link
Member Author

While there are still some outstanding cases to investigate regarding keys, I don't know that they should be a blocker for this PR. Without this PR those keys are currently still typed as string anyways, and there is a long tail of cases where we are still using Maps as Set-likes, or with string keys that are coerced, that I plan to address over time rather than in a single PR.

rbuckton added 2 commits June 22, 2020 18:53
# Conflicts:
#	src/server/project.ts
#	src/services/types.ts
@rbuckton
Copy link
Member Author

@sheetalkamat can you take another look?

Copy link
Member

@sheetalkamat sheetalkamat left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apart from two suggestions things look good.

Here are two questions i still have:
1: There are some places where you replaced createMap() with new Map() but not all. Was there a reason for that
2. Do we really care about performance of shim implementaion if we were really using the native maps before.. Why not use .toString() on key for shim to keep it simple and compact if its going to be used rarely.

src/harness/virtualFileSystemWithWatch.ts Outdated Show resolved Hide resolved
@sheetalkamat
Copy link
Member

Sorry didnt notice your questions on the previous comments,going through them now

@rbuckton
Copy link
Member Author

Here are two questions i still have:
1: There are some places where you replaced createMap() with new Map() but not all. Was there a reason for that

Those were mostly ad-hoc. I am planning on putting together a follow-up PR that replaces all other references and removes createMap.

  1. Do we really care about performance of shim implementaion if we were really using the native maps before.. Why not use .toString() on key for shim to keep it simple and compact if its going to be used rarely.

Using .toString won't work for non-primitive values, and wouldn't handle cases like null, undefined, true, false, +Infinity, -Infinity, and NaN. The approach in this PR is to give these types different buckets to work with to avoid collisions (i.e. 1 and "1" should not collide) and still have moderately fast lookup time for common cases (i.e., strings and numbers).

If the recommendation is to ignore performance for the shim and simplify the design, then I'd likely just do away with the buckets and use the linked list implementation used for other values for everything.

One of the stated goals for this PR is to allow us to have non-primitive keys. While I am not making heavy use of it in this PR, I plan to migrate some of our maps/sets to accept Node or Symbol keys in follow-up PRs, in an effort to reduce the unnecessary overhead of calling getNodeId or getSymbolId just to use as a key for a Map/Set.

@rbuckton
Copy link
Member Author

@sheetalkamat: I've put together a simpler (though less performant) version of the shim that just uses a linked list. Should I use that one instead?

@rbuckton
Copy link
Member Author

I'll go ahead and switch to the simpler Map/Set implementation that just leverages a linked list. It will be less performant, but also takes up less memory and reduces the file-size cost of the shim.

@rbuckton
Copy link
Member Author

@sheetalkamat: Would you care to take one more look over the shim implementation? I repurposed the existing doubly-linked list that was added to preserve iteration order, which should result in less memory usage overall.

@rbuckton rbuckton mentioned this pull request Jun 25, 2020
@rbuckton
Copy link
Member Author

@sheetalkamat: I've filed #39264 which leverages the work in this PR and comprehensively removes calls to createMap, as well as some other related cleanup.

@rbuckton rbuckton merged commit eb2f4e2 into master Jun 26, 2020
@rbuckton rbuckton deleted the esMapSetShim branch June 26, 2020 17:12
cangSDARM added a commit to cangSDARM/TypeScript that referenced this pull request Jun 28, 2020
* upstream/master:
  LEGO: check in for master to temporary branch.
  Preserve newlines between try/catch/finally, if/else, do/while (microsoft#39280)
  not narrow static property without type annotation in constructor. (microsoft#39252)
  Switch to ES Map/Set internally (microsoft#33771)
  fix(38840): omit completions for a spread like argument in a function definition (microsoft#38897)
  fix(38785): include in NavigationBar child items from default exported functions (microsoft#38915)
  LEGO: check in for master to temporary branch.
  LEGO: check in for master to temporary branch.
  Avoid effect of element access expression (microsoft#39174)
  Update typescript-eslint to 3.4.1-alpha.1 (microsoft#39260)
  Handle 'keyof' for generic tuple types (microsoft#39218)
  Disable unsound T[K] rule in subtype relations (microsoft#39249)
  LEGO: check in for master to temporary branch.
  Upgrade typescript-eslint version (microsoft#39242)
  Handle recursive type references up to a certain level of expansion in inference (microsoft#38011)
  Do not consider binding patterns in contextual types for return type inference where all the signature type parameters have defaults (microsoft#39081)
  LEGO: check in for master to temporary branch.

# Conflicts:
#	src/compiler/program.ts
#	src/compiler/types.ts
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants