-
Notifications
You must be signed in to change notification settings - Fork 7
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
branch: createArrayProxy #252
Comments
In the above commits, I converted to createArrayProxy. |
Hmm... We have a problem with "Start Over" and "Reset All" performance. Testing on my MacBookPro16,1 + macOS 10.15.6 + Chrome 85.0.4183.121 :
Before I dive in... @samreid any thoughts on what could be causing this? Steps to reproduce:
|
On my Mac/Chrome, with this URL (no assertions): I see 80ms in master, and 1071ms in the branch (for Start Over). After this patch: Index: main/tandem/js/PhetioGroup.js
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- main/tandem/js/PhetioGroup.js (revision 2f8159ca6f9a3758a6ffaef9f9071ee5512aa0c8)
+++ main/tandem/js/PhetioGroup.js (date 1601353233469)
@@ -199,7 +199,7 @@
}, options );
while ( this._array.length > 0 ) {
- this.disposeElement( this._array[ this._array.length - 1 ], options.fromStateSetting );
+ this.disposeElement( this._array[ 0 ], options.fromStateSetting );
}
if ( options.resetIndex ) {
Index: main/natural-selection/js/common/model/BunnyCollection.js
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- main/natural-selection/js/common/model/BunnyCollection.js (revision eb577bbef918ace3341eaa120f8997d755c3584e)
+++ main/natural-selection/js/common/model/BunnyCollection.js (date 1601353158855)
@@ -177,9 +177,15 @@
// When a bunny is disposed, remove it from the appropriate array. removeListener is not necessary.
bunnyGroup.elementDisposedEmitter.addListener( bunny => {
assert && assert( bunny instanceof Bunny, 'invalid bunny' );
- this.liveBunnies.includes( bunny ) && this.liveBunnies.remove( bunny );
- this.deadBunnies.includes( bunny ) && this.deadBunnies.remove( bunny );
- this.recessiveMutants.includes( bunny ) && this.recessiveMutants.remove( bunny );
+
+ const liveIndex = this.liveBunnies.indexOf( bunny );
+ liveIndex >= 0 && this.liveBunnies.splice( liveIndex, 1 );
+
+ const deadIndex = this.deadBunnies.indexOf( bunny );
+ deadIndex >= 0 && this.deadBunnies.splice( deadIndex, 1 );
+
+ const recessiveIndex = this.recessiveMutants.indexOf( bunny );
+ recessiveIndex >= 0 && this.recessiveMutants.splice( recessiveIndex, 1 );
} );
// @private fields needed by methods
I'm seeing 87ms in the branch. |
I committed the change in PhetioGroup. @zepumph can you please review it? It changes PhetioGroup removal from First In/Last Out to First In/First Out so that, if you go in order, Also leaving assigned to @pixelzoom to apply the performance improvements in BunnyCollection.js. |
That looks really nice. Good work! |
The improvement to BunnyCollection is a lot of boilerplate. I investigated using arrayRemove.js, but it seems like that functionality should be rolled into createArrayProxy.js. My recommendation is to plan on keeping - remove: function( element ) { this.includes( element ) && arrayRemove( this, element );},
+ remove: function( element, required = true ) {
+ const index = this.indexOf( element );
+ required && assert && assert( index >= 0, 'item not found in Array' );
+ this.splice( index, 1 );
+ } I'm not wild about the - remove: function( element ) { this.includes( element ) && arrayRemove( this, element );},
+ remove: function( element ) {
+ const index = this.indexOf( element );
+ assert && assert( index >= 0, 'item not found in Array' );
+ this.splice( index, 1 );
+ }
+
+ removeIfIncludes: function( element ) {
+ const index = this.indexOf( element );
+ if ( index >= 0 ) {
+ this.splice( index, 1 );
+ }
+ } @samreid thoughts? |
It would probably be fine to have arrayRemove(myArray,element);
arrayRemoveIfIncludes(myArray,element); |
@samreid which of these do you prefer? (A) Client is responsible for getting and checking index, then doing splice. Lots of boilerplate. bunnyGroup.elementDisposedEmitter.addListener( bunny => {
assert && assert( bunny instanceof Bunny, 'invalid bunny' );
const liveIndex = this.liveBunnies.indexOf( bunny );
liveIndex >= 0 && this.liveBunnies.splice( liveIndex, 1 );
const deadIndex = this.deadBunnies.indexOf( bunny );
deadIndex >= 0 && this.deadBunnies.splice( deadIndex, 1 );
const recessiveIndex = this.recessiveMutants.indexOf( bunny );
recessiveIndex >= 0 && this.recessiveMutants.splice( recessiveIndex, 1 );
} ); (B) Above boilerplate factored out into standalone functions. Not object-oriented, requires additional imports. import arrayRemove from '../../../../phet-core/js/arrayRemove.js';
import arrayRemoveIfIncludes from '../../../../phet-core/js/arrayRemoveIfIncludes.js';
bunnyGroup.elementDisposedEmitter.addListener( bunny => {
assert && assert( bunny instanceof Bunny, 'invalid bunny' );
arrayRemoveIfIncludes( this.liveBunnies, bunny );
arrayRemoveIfIncludes( this.deadBunnies, bunny );
arrayRemoveIfIncludes( this.recessiveMutants, bunny );
} ); (C) ArrayProxyDef extended to provide a better "remove" API. New methods are not compatible with back-porting to Array. bunnyGroup.elementDisposedEmitter.addListener( bunny => {
assert && assert( bunny instanceof Bunny, 'invalid bunny' );
this.liveBunnies.removeIfIncludes( bunny );
this.deadBunnies.removeIfIncludes( bunny );
this.recessiveMutants.removeIfIncludes( bunny );
} ); |
I recommend we start with (C) for now, but if we eventually need to move back and forth between ArrayProxy -> Array in the future, we could consider (B). |
Great, because I have a strong preference for (C). I'll modify createArrayProxy.js accordingly and proceed with NS changes. |
Once I got further into this, I bailed on any changes to the "remove" API for ArrayProxyDef. I unfortunately stuck with approach (A) (boilerplate) for now. In the above commit, I replaced uses of ArrayProxyDef Unbuilt testing with I also verified that memory footprint has not changed, using the procedure in #232. |
Oh rats... I did d325a40 in master. Stand by while I fix this. |
This branch stopped working with master dependencies because of changes to IO Types. So I manually merged what I could into master, and I'm giving up on this branch. Everything seems to be working OK in master, so I'll close this issue and delete this branch. |
For https://github.com/phetsims/special-ops/issues/198, this branch needs to be deleted again. Reopening and self assigning. |
Re-deleted using GitHub UI. Closing. |
This is a branch for experimenting with createArrayProxy.js, a potential replacement for ObservableArray. See phetsims/axon#330.
The text was updated successfully, but these errors were encountered: