Skip to content

Switch to ES Map/Set internally - #33771

Merged
rbuckton merged 15 commits into
masterfrom
esMapSetShim
Jun 26, 2020
Merged

Switch to ES Map/Set internally#33771
rbuckton merged 15 commits into
masterfrom
esMapSetShim

Conversation

@rbuckton

@rbucktonrbuckton commented Oct 2, 2019

Copy link
Copy Markdown
Contributor

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
rbucktonforce-pushed the esMapSetShim branch 3 times, most recently from e4769a2 to 374ce8bCompareOctober 7, 2019 20:49
@j-oliverasj-oliveras mentioned this pull request Oct 8, 2019
@rbucktonrbuckton changed the title ES Map/Set/WeakMap/WeakSet shimsSwitch to ES Map/Set/WeakMap/WeakSet internallyJun 18, 2020
@rbucktonrbuckton changed the title Switch to ES Map/Set/WeakMap/WeakSet internallySwitch to ES Map/Set internallyJun 19, 2020
@rbuckton
rbuckton marked this pull request as ready for review June 19, 2020 06:44
@rbuckton

Copy link
Copy Markdown
ContributorAuthor

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

@typescript-bot

typescript-bot commented Jun 19, 2020

Copy link
Copy Markdown
Contributor

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

typescript-bot commented Jun 19, 2020

Copy link
Copy Markdown
Contributor

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

@typescript-bot

typescript-bot commented Jun 19, 2020

Copy link
Copy Markdown
Contributor

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

typescript-bot commented Jun 19, 2020

Copy link
Copy Markdown
Contributor

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
Copy Markdown
Contributor

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

Here they are:

Comparison Report - master..33771

Metricmaster33771DeltaBestWorst
Angular - node (v10.16.3, x64)
Memory used340,339k (± 0.01%)339,863k (± 0.02%)-475k (- 0.14%)339,715k340,021k
Parse Time1.99s (± 0.85%)1.99s (± 0.55%)-0.00s (- 0.25%)1.97s2.01s
Bind Time0.80s (± 0.65%)0.80s (± 0.72%)-0.00s (- 0.12%)0.79s0.81s
Check Time4.73s (± 0.57%)4.70s (± 0.31%)-0.03s (- 0.57%)4.67s4.74s
Emit Time5.22s (± 0.80%)5.15s (± 0.61%)-0.07s (- 1.36%)5.08s5.22s
Total Time12.74s (± 0.45%)12.64s (± 0.31%)-0.10s (- 0.78%)12.54s12.69s
Monaco - node (v10.16.3, x64)
Memory used338,915k (± 0.02%)338,981k (± 0.02%)+66k (+ 0.02%)338,848k339,169k
Parse Time1.58s (± 0.41%)1.58s (± 0.60%)-0.00s (- 0.32%)1.56s1.61s
Bind Time0.70s (± 0.83%)0.70s (± 1.04%)+0.00s (+ 0.14%)0.68s0.71s
Check Time4.86s (± 0.44%)4.86s (± 0.65%)+0.00s (+ 0.02%)4.78s4.93s
Emit Time2.75s (± 0.94%)2.75s (± 1.00%)+0.00s (+ 0.00%)2.69s2.82s
Total Time9.89s (± 0.46%)9.88s (± 0.45%)-0.01s (- 0.07%)9.81s9.98s
TFS - node (v10.16.3, x64)
Memory used301,939k (± 0.08%)301,897k (± 0.02%)-42k (- 0.01%)301,785k302,051k
Parse Time1.21s (± 0.84%)1.21s (± 0.63%)-0.00s (- 0.41%)1.18s1.22s
Bind Time0.66s (± 0.76%)0.65s (± 0.89%)-0.01s (- 0.76%)0.63s0.66s
Check Time4.37s (± 0.69%)4.36s (± 0.34%)-0.01s (- 0.21%)4.32s4.39s
Emit Time2.89s (± 0.99%)2.90s (± 0.79%)+0.00s (+ 0.17%)2.86s2.97s
Total Time9.12s (± 0.64%)9.12s (± 0.39%)-0.01s (- 0.09%)9.03s9.21s
material-ui - node (v10.16.3, x64)
Memory used459,485k (± 0.01%)459,320k (± 0.01%)-165k (- 0.04%)459,216k459,494k
Parse Time2.05s (± 0.53%)2.05s (± 0.47%)-0.00s (- 0.15%)2.03s2.07s
Bind Time0.66s (± 1.63%)0.65s (± 1.28%)-0.01s (- 1.97%)0.63s0.67s
Check Time12.81s (± 0.67%)12.88s (± 0.99%)+0.07s (+ 0.52%)12.66s13.20s
Emit Time0.00s (± 0.00%)0.00s (± 0.00%)0.00s ( NaN%)0.00s0.00s
Total Time15.52s (± 0.54%)15.58s (± 0.83%)+0.06s (+ 0.37%)15.34s15.87s
Angular - node (v12.1.0, x64)
Memory used317,771k (± 0.02%)317,337k (± 0.01%)-434k (- 0.14%)317,253k317,400k
Parse Time1.97s (± 0.67%)1.95s (± 1.07%)-0.02s (- 0.86%)1.91s1.99s
Bind Time0.78s (± 0.79%)0.78s (± 0.83%)-0.00s (- 0.13%)0.77s0.79s
Check Time4.58s (± 0.61%)4.58s (± 0.42%)-0.00s (- 0.09%)4.53s4.62s
Emit Time5.34s (± 0.99%)5.38s (± 1.28%)+0.04s (+ 0.71%)5.25s5.54s
Total Time12.67s (± 0.64%)12.68s (± 0.76%)+0.01s (+ 0.09%)12.50s12.95s
Monaco - node (v12.1.0, x64)
Memory used321,471k (± 0.02%)321,455k (± 0.02%)-16k (- 0.01%)321,349k321,576k
Parse Time1.54s (± 0.91%)1.53s (± 0.58%)-0.01s (- 0.58%)1.51s1.55s
Bind Time0.67s (± 0.71%)0.67s (± 0.77%)-0.00s (- 0.30%)0.66s0.68s
Check Time4.65s (± 0.59%)4.65s (± 0.51%)+0.00s (+ 0.04%)4.60s4.70s
Emit Time2.79s (± 0.73%)2.81s (± 0.82%)+0.02s (+ 0.72%)2.77s2.87s
Total Time9.66s (± 0.53%)9.67s (± 0.36%)+0.01s (+ 0.16%)9.57s9.75s
TFS - node (v12.1.0, x64)
Memory used286,358k (± 0.02%)286,360k (± 0.03%)+2k (+ 0.00%)286,261k286,697k
Parse Time1.23s (± 0.77%)1.22s (± 0.54%)-0.01s (- 1.13%)1.21s1.24s
Bind Time0.62s (± 1.42%)0.62s (± 1.20%)-0.00s (- 0.48%)0.60s0.64s
Check Time4.28s (± 0.60%)4.26s (± 0.31%)-0.02s (- 0.40%)4.23s4.28s
Emit Time2.95s (± 1.63%)2.91s (± 0.97%)-0.04s (- 1.25%)2.87s2.99s
Total Time9.08s (± 0.54%)9.01s (± 0.33%)-0.07s (- 0.74%)8.94s9.09s
material-ui - node (v12.1.0, x64)
Memory used437,853k (± 0.06%)437,446k (± 0.09%)-407k (- 0.09%)436,451k437,807k
Parse Time2.03s (± 0.69%)2.01s (± 0.68%)-0.02s (- 0.79%)1.99s2.05s
Bind Time0.64s (± 0.70%)0.63s (± 1.16%)-0.01s (- 1.57%)0.62s0.65s
Check Time11.58s (± 1.08%)11.61s (± 1.26%)+0.03s (+ 0.24%)11.33s12.00s
Emit Time0.00s (± 0.00%)0.00s (± 0.00%)0.00s ( NaN%)0.00s0.00s
Total Time14.26s (± 0.94%)14.25s (± 1.06%)-0.00s (- 0.01%)13.97s14.66s
Angular - node (v8.9.0, x64)
Memory used336,820k (± 0.02%)336,482k (± 0.01%)-339k (- 0.10%)336,339k336,547k
Parse Time2.49s (± 0.40%)2.49s (± 0.46%)-0.00s (- 0.04%)2.46s2.51s
Bind Time0.83s (± 0.96%)0.83s (± 0.69%)-0.00s (- 0.24%)0.82s0.84s
Check Time5.31s (± 0.54%)5.34s (± 0.51%)+0.04s (+ 0.66%)5.26s5.39s
Emit Time5.84s (± 1.65%)5.93s (± 1.01%)+0.09s (+ 1.47%)5.85s6.13s
Total Time14.48s (± 0.71%)14.60s (± 0.40%)+0.12s (+ 0.80%)14.50s14.77s
Monaco - node (v8.9.0, x64)
Memory used340,275k (± 0.02%)340,274k (± 0.01%)-1k (- 0.00%)340,177k340,389k
Parse Time1.86s (± 0.43%)1.87s (± 0.64%)+0.01s (+ 0.32%)1.85s1.91s
Bind Time0.87s (± 0.57%)0.86s (± 0.79%)-0.00s (- 0.23%)0.85s0.88s
Check Time5.34s (± 0.63%)5.35s (± 0.46%)+0.00s (+ 0.09%)5.28s5.40s
Emit Time3.23s (± 0.71%)3.21s (± 0.36%)-0.02s (- 0.56%)3.18s3.23s
Total Time11.30s (± 0.43%)11.29s (± 0.32%)-0.01s (- 0.09%)11.23s11.37s
TFS - node (v8.9.0, x64)
Memory used303,635k (± 0.02%)303,624k (± 0.02%)-11k (- 0.00%)303,531k303,721k
Parse Time1.54s (± 0.84%)1.54s (± 0.54%)+0.01s (+ 0.59%)1.53s1.56s
Bind Time0.65s (± 0.85%)0.65s (± 0.80%)-0.00s (- 0.15%)0.64s0.66s
Check Time5.00s (± 1.74%)4.93s (± 1.55%)-0.07s (- 1.38%)4.83s5.11s
Emit Time3.04s (± 2.55%)3.10s (± 3.19%)+0.05s (+ 1.77%)2.84s3.23s
Total Time10.24s (± 0.33%)10.23s (± 0.52%)-0.01s (- 0.10%)10.08s10.36s
material-ui - node (v8.9.0, x64)
Memory used463,634k (± 0.01%)463,383k (± 0.01%)-251k (- 0.05%)463,291k463,450k
Parse Time2.39s (± 0.60%)2.37s (± 0.49%)-0.02s (- 0.67%)2.35s2.40s
Bind Time0.77s (± 1.52%)0.77s (± 1.30%)-0.00s (- 0.52%)0.75s0.80s
Check Time17.12s (± 1.31%)16.91s (± 1.14%)-0.21s (- 1.20%)16.42s17.20s
Emit Time0.00s (± 0.00%)0.00s (±222.80%)🔻+0.00s (+ ∞%)0.00s0.01s
Total Time20.28s (± 1.19%)20.05s (± 0.98%)-0.23s (- 1.11%)19.57s20.36s
Angular - node (v8.9.0, x86)
Memory used193,337k (± 0.02%)193,172k (± 0.02%)-165k (- 0.09%)193,074k193,281k
Parse Time2.45s (± 0.96%)2.42s (± 0.85%)-0.03s (- 1.10%)2.38s2.48s
Bind Time0.98s (± 0.97%)0.97s (± 0.77%)-0.01s (- 0.92%)0.95s0.98s
Check Time4.80s (± 0.57%)4.79s (± 0.63%)-0.01s (- 0.23%)4.73s4.85s
Emit Time5.97s (± 1.22%)5.92s (± 1.25%)-0.05s (- 0.92%)5.70s6.09s
Total Time14.20s (± 0.74%)14.10s (± 0.68%)-0.10s (- 0.74%)13.83s14.32s
Monaco - node (v8.9.0, x86)
Memory used193,279k (± 0.03%)193,295k (± 0.01%)+16k (+ 0.01%)193,241k193,346k
Parse Time1.90s (± 0.63%)1.90s (± 0.82%)-0.00s (- 0.05%)1.87s1.94s
Bind Time0.68s (± 0.87%)0.68s (± 0.70%)-0.00s (- 0.15%)0.67s0.69s
Check Time5.44s (± 0.40%)5.44s (± 0.47%)-0.00s (- 0.02%)5.39s5.50s
Emit Time2.67s (± 0.87%)2.67s (± 0.69%)-0.00s (- 0.11%)2.64s2.73s
Total Time10.70s (± 0.43%)10.69s (± 0.42%)-0.00s (- 0.05%)10.61s10.81s
TFS - node (v8.9.0, x86)
Memory used173,586k (± 0.03%)173,598k (± 0.02%)+12k (+ 0.01%)173,516k173,659k
Parse Time1.58s (± 0.72%)1.57s (± 0.57%)-0.00s (- 0.25%)1.56s1.60s
Bind Time0.62s (± 0.55%)0.63s (± 1.59%)+0.01s (+ 1.62%)0.61s0.66s
Check Time4.66s (± 0.53%)4.65s (± 1.04%)-0.01s (- 0.15%)4.55s4.77s
Emit Time2.81s (± 1.91%)2.80s (± 1.57%)-0.02s (- 0.53%)2.70s2.90s
Total Time9.66s (± 0.60%)9.65s (± 0.82%)-0.02s (- 0.17%)9.49s9.84s
material-ui - node (v8.9.0, x86)
Memory used262,444k (± 0.02%)262,304k (± 0.02%)-140k (- 0.05%)262,208k262,415k
Parse Time2.44s (± 0.70%)2.45s (± 0.73%)+0.00s (+ 0.04%)2.41s2.49s
Bind Time0.67s (± 1.59%)0.66s (± 1.40%)-0.00s (- 0.60%)0.65s0.69s
Check Time15.55s (± 0.49%)15.48s (± 0.70%)-0.07s (- 0.44%)15.30s15.81s
Emit Time0.00s (± 0.00%)0.00s (± 0.00%)0.00s ( NaN%)0.00s0.00s
Total Time18.67s (± 0.43%)18.60s (± 0.52%)-0.07s (- 0.37%)18.44s18.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)
BenchmarkNameIterations
Current3377110
Baselinemaster10

Comment threadsrc/compiler/binder.ts Outdated
Comment threadsrc/compiler/program.ts Outdated
Comment threadsrc/compiler/program.ts Outdated
Comment threadsrc/compiler/program.ts Outdated
# Conflicts:
#	src/services/refactors/extractSymbol.ts
Comment threadsrc/compiler/builderState.ts Outdated
if (!options.noEmit && !options.suppressOutputPathCheck) {
const emitHost = getEmitHost();
const emitFilesSeen = createMap<true>();
const emitFilesSeen = new Set<string>();

Copy link
Copy Markdown
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
Copy Markdown
ContributorAuthor

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
Copy Markdown
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.

Comment threadsrc/compiler/program.ts Outdated
Comment threadsrc/compiler/resolutionCache.ts Outdated
Comment threadsrc/compiler/resolutionCache.ts Outdated
Comment threadsrc/server/session.ts Outdated
Comment threadsrc/services/documentRegistry.ts Outdated
Comment threadsrc/services/documentRegistry.ts Outdated
Comment threadsrc/services/services.ts Outdated
Comment threadsrc/shims/collectionShims.ts Outdated
@rbuckton

Copy link
Copy Markdown
ContributorAuthor

@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
Copy Markdown
ContributorAuthor

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.

# Conflicts:
#	src/server/project.ts
#	src/services/types.ts
@rbuckton

Copy link
Copy Markdown
ContributorAuthor

@sheetalkamat can you take another look?

@sheetalkamatsheetalkamat left a comment

Copy link
Copy Markdown
Member

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.

Comment threadsrc/harness/virtualFileSystemWithWatch.ts Outdated
@sheetalkamat

Copy link
Copy Markdown
Member

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

@rbuckton

Copy link
Copy Markdown
ContributorAuthor

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
Copy Markdown
ContributorAuthor

@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
Copy Markdown
ContributorAuthor

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
Copy Markdown
ContributorAuthor

@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.

@rbucktonrbuckton mentioned this pull request Jun 25, 2020
@rbuckton

Copy link
Copy Markdown
ContributorAuthor

@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 masterJun 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
@microsoftmicrosoft locked as resolved and limited conversation to collaborators Oct 21, 2025
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@rbuckton@typescript-bot@sheetalkamat