-
-
Notifications
You must be signed in to change notification settings - Fork 4.2k
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
get() / set() perf optimizations #17166
Changes from all commits
1eb257e
5cf6543
a51c182
cbbc4c4
89acaf9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -34,11 +34,10 @@ let deferred = 0; | |
@since 3.1.0 | ||
@public | ||
*/ | ||
function notifyPropertyChange(obj: object, keyName: string, _meta?: Meta): void { | ||
function notifyPropertyChange(obj: object, keyName: string, _meta?: Meta | null): void { | ||
let meta = _meta === undefined ? peekMeta(obj) : _meta; | ||
let hasMeta = meta !== undefined; | ||
|
||
if (hasMeta && (meta.isInitializing() || meta.isPrototypeMeta(obj))) { | ||
if (meta !== null && (meta.isInitializing() || meta.isPrototypeMeta(obj))) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why not check once and reference it like before There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Because the ts linter won't recognize that meta is non-null, and the subsequent statements would need a "!": if (hasMeta && (meta!.isInitializing() || meta!.isPrototypeMeta(obj))) { |
||
return; | ||
} | ||
|
||
|
@@ -48,7 +47,7 @@ function notifyPropertyChange(obj: object, keyName: string, _meta?: Meta): void | |
possibleDesc.didChange(obj, keyName); | ||
} | ||
|
||
if (hasMeta && meta.peekWatching(keyName) > 0) { | ||
if (meta !== null && meta.peekWatching(keyName) > 0) { | ||
dependentKeysDidChange(obj, keyName, meta); | ||
chainsDidChange(obj, keyName, meta); | ||
notifyObservers(obj, keyName, meta); | ||
|
@@ -58,7 +57,7 @@ function notifyPropertyChange(obj: object, keyName: string, _meta?: Meta): void | |
obj[PROPERTY_DID_CHANGE](keyName); | ||
} | ||
|
||
if (hasMeta) { | ||
if (meta !== null) { | ||
if (meta.isSourceDestroying()) { | ||
return; | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -96,6 +96,10 @@ export function get(obj: object, keyName: string): any { | |
let isFunction = type === 'function'; | ||
let isObjectLike = isObject || isFunction; | ||
|
||
if (isPath(keyName)) { | ||
return isObjectLike ? _getPath(obj, keyName) : undefined; | ||
} | ||
|
||
let value: any; | ||
|
||
if (isObjectLike) { | ||
|
@@ -119,9 +123,6 @@ export function get(obj: object, keyName: string): any { | |
} | ||
|
||
if (value === undefined) { | ||
if (isPath(keyName)) { | ||
return _getPath(obj, keyName); | ||
} | ||
if ( | ||
isObject && | ||
!(keyName in obj) && | ||
|
@@ -133,9 +134,9 @@ export function get(obj: object, keyName: string): any { | |
return value; | ||
} | ||
|
||
export function _getPath<T extends object>(root: T, path: string): any { | ||
export function _getPath<T extends object>(root: T, path: string | string[]): any { | ||
let obj: any = root; | ||
let parts = path.split('.'); | ||
let parts = typeof path === 'string' ? path.split('.') : path; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it will be even more performant if There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, I thought about that, and you might be right. I discarded it as a micro optimization I didn't want to do in this pass. It is not likely to make any measurable difference. |
||
|
||
for (let i = 0; i < parts.length; i++) { | ||
if (obj === undefined || obj === null || (obj as MaybeHasIsDestroyed).isDestroyed) { | ||
|
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.
Note: I use
Map.forEach()
for the iteration, since it is the only method that works with IE11.