-
Notifications
You must be signed in to change notification settings - Fork 12.6k
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
Add StringMap, NumberMap, and StringSet data structures #10230
Conversation
…e available, to replace the old Map, which is now ObjMap.
} | ||
|
||
/** String-keyed Map. */ | ||
export interface SMap<V> extends MapCommon<string, V> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: I think it will be easier to read if you just use StringMap
instead of SMap
and same as NumberMap
for NMap
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On that topic, what should we name ObjMap
? (The keys aren't objects. The map itself is an object, which is used like a StringMap
.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
NumberKeyedMap
, StringKeyedMap
, ObjectBackedMap
. With good autcomplete, there's no real reason for confusing or ambiguous hungarianesque notation.
@@ -1399,7 +1397,7 @@ namespace ts { | |||
|
|||
const typeLiteralSymbol = createSymbol(SymbolFlags.TypeLiteral, "__type"); | |||
addDeclarationToSymbol(typeLiteralSymbol, node, SymbolFlags.TypeLiteral); | |||
typeLiteralSymbol.members = { [symbol.name]: symbol }; | |||
typeLiteralSymbol.members = singletonMap(symbol.name, symbol); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the purpose of singletonMap?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thought it was neater than new SMap([[symbol.name, symbol]])
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nothing about this is like a singleton
in the design pattern sense (it's a loaded term), so the name is a bit confusing. createStringKeyedMap
would be more straightforward, if you must wrap the constructor.
This appears to sort object type keys (which is causing what should be a transparent change to manifest in our baselines). With this change sort order is now insertion order (which arguably is nice), however this is likely a problem because the polyfills right now don't do the same sorting. (This may surface as node 0.10 failing CI with mismatching baselines once the other bugs are fixed) |
export const SSet: SSetConstructor = Set ? Set : ShimSSet; | ||
|
||
/** False iff there are any values in the set. */ | ||
export function setIsEmpty(set: SSet): boolean { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this be isSetEmpty?
Could you also please share some numbers on how this effect both memory and performance in the typescript repo and other use cases? |
Overall, we get about a 10% reduction of both memory and total time. (We could get even more by changing the emitter to use StringMaps.) (Note: since file system accesses are cached, I throw away the first run, which has a large I/O read time.) VSCodeTesting on the latest checkout of Microsoft/vscode: Constant:
Typescript servicesTesting on the
Single fileJust a file with
Interactive testWhat I did:
|
@andy-ms what were the numbers if we are using the shims and not the native implementation? |
The shims caused an increase in memory due to indirection: the shim was an object pointing to another object in dictionary mode. With native maps:
With the shims always used:
I have created a new PR #11210 which fixes this issue. |
This switches us to using native Maps and Sets where possible.
Since we can't guarantee that the native
Map
will exist, we instead haveStringMap
andNumberMap
for string-keyed and number-keyed maps, with shims using objects and arrays.Many remaining uses of the old
Map
may be better off asStringMap
, but I've left alone anything that looks public-facing.I've also mostly left
declarationEmitter
andemitter
alone. When we merge the transforms branch in we should use the new maps there.I'd like to assign @rakatyal to this but it looks like he's not yet on the available assignees list.