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

improve responsiveness of "Start Over" button #140

Closed
pixelzoom opened this issue Jul 22, 2020 · 27 comments
Closed

improve responsiveness of "Start Over" button #140

pixelzoom opened this issue Jul 22, 2020 · 27 comments

Comments

@pixelzoom
Copy link
Contributor

Responsiveness of the "Start Over" button was identified as an issue in #60 (comment). It could use improvement for brand=phet, and is unacceptable with brand=phet-io.

@pixelzoom
Copy link
Contributor Author

Query parameters showTimes has been added. It shows both the time to mate, and the time to perform 'Start Over', in the upper-left corner of the screen, e.g.:

screenshot_435

@pixelzoom
Copy link
Contributor Author

pixelzoom commented Jul 28, 2020

First, let's quantify performance.

Steps:

  1. Run the sim, using links below.
  2. Go to Lab screen
  3. Press "Add a Mate" button.
  4. Wait for bunnies to take over the world. Close dialog.
  5. Press "Start Over" button, record time1.
  6. Press "Add a Mate" button.
  7. Wait for bunnies to take over the world. Close dialog.
  8. Press "Start Over" button, record time2.
  9. Press "Add a Mate" button.
  10. Wait for bunnies to take over the world. Close dialog.
  11. Press "Start Over" button, record time3.
  12. Record average of 3 times.

For brand=phet, run https://phet-dev.colorado.edu/html/natural-selection/1.0.0-dev.75/phet/natural-selection_en_phet.html?showTimes&secondsPerGeneration=1. Follow the steps above. Enter the browser versions and times (in ms) in this table:

test device OS browser time1 (ms) time2 (ms) time3 (ms) average (ms)
PixelZoom - 2019 MacBook Pro macOS 10.15.5 Safari 13.1.1 62 56 48 55
PixelZoom - 2019 MacBook Pro macOS 10.15.5 Chrome 84.0.4147.105 85 74 68 76
PixelZoom - 2009 MacBook Pro macOS 10.11.6 Safari 11.1.2 251 179 159 196
PixelZoom - 2009 MacBook Pro macOS 10.11.6 Chrome 84.0.4147.105 176 142 151 156
PixelZoom - iPad6 iOS 13.5.1 Safari 13 97 94 77 89
Katie's Dell Win 10 Edge ???
Katie's Dell Win 10 Chrome 84.0.4147.105
Katie's Dell Win 10 Firefox ???
Katie's iPhone 7 iOS 13.5.1 Safari Mobile 13
Lovelace - Chromebook ChromeOS Chrome ???
Dirac - MacBook Pro macOS 10.12.6 Safari 12.1.2
Hooper - iPad6 iOS 12.4.1 Safari Mobile 12
Dirac - MacBook Pro macOS 10.12.6 Safari 12.1.2
Jordan - MacBook Air macOS 10.13.6 Safari 13.1.1

For brand=phet-io, run https://phet-dev.colorado.edu/html/natural-selection/1.0.0-dev.75/phet-io/natural-selection_all_phet-io.html?postMessageOnError&phetioStandalone&showTimes&secondsPerGeneration=1. Follow the steps above. Enter the browser versions and times (in ms) in this table:

test device OS browser time1 (ms) time2 (ms) time3 (ms) average (ms)
PixelZoom - 2019 MacBook Pro macOS 10.15.5 Safari 13.1.1 1201 1236 1286 1241
PixelZoom - 2019 MacBook Pro macOS 10.15.5 Chrome 84.0.4147.105 849 883 886 873
PixelZoom - 2009 MacBook Pro macOS 10.11.6 Safari 11.1.2 9381 9046 8926 9118
PixelZoom - 2009 MacBook Pro macOS 10.11.6 Chrome 84.0.4147.105 2016 1741 1720 1826
PixelZoom - iPad6 iOS 13.5.1 Safari 13 3707 4254 3897 3953
Katie's Dell Win 10 Edge ???
Katie's Dell Win 10 Chrome 84.0.4147.105
Katie's Dell Win 10 Firefox ???
Katie's iPhone 7 iOS 13.5.1 Safari Mobile 13
Lovelace - Chromebook ChromeOS Chrome ???
Dirac - MacBook Pro macOS 10.12.6 Safari 12.1.2
Hooper - iPad6 iOS 12.4.1 Safari Mobile 12
Dirac - MacBook Pro macOS 10.12.6 Safari 12.1.2
Jordan - MacBook Air macOS 10.13.6 Safari 13.1.1

@pixelzoom
Copy link
Contributor Author

pixelzoom commented Jul 28, 2020

I completed the first 5 rows in each table. brand=phet performance was acceptable in all cases. brand=phet-io performance is unacceptable. Safari (for example) took 22x as long as brand=phet on a 2019 MacBook Pro!

@KatieWoe could you please complete the remaining rows in the above tables?

@pixelzoom
Copy link
Contributor Author

bunnyGroup.clear() is taking the vast majority of the time. For example, with Safari 13 on my 2019 MacBook Pro, total time for model.startOver is 898 ms, of which 893 is spent in bunnyGroup.clear.

@pixelzoom
Copy link
Contributor Author

pixelzoom commented Jul 28, 2020

@samreid and I paired on this via Zoom. We identified 2 performance bottlenecks in code that runs only for PhET-iO brand.

  • PropertyStateHandler.js unregisterOrderDependenciesForProperty contains a loop that is O(N2). Percentage varies by platform, but was ~25% of Chrome.

  • phetioStateEngine.js phetioObjectRemoved spends a large amount of time in this.phetioIDs.indexOf( phetioID ); Percentage varies by platform, but was > 10%.

To investigate what kind of performance improvement we might get, we commented out the body of unregisterOrderDependenciesForProperty. And @samreid put together this experimental patch to remove this.phetioIDs from phetioStateEngine.js:

patch
Index: js/PhetioStateEngine.js
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- js/PhetioStateEngine.js	(revision 675b683ee10353c13d7c162beaede92a47fe6dff)
+++ js/PhetioStateEngine.js	(date 1595978134546)
@@ -152,7 +152,7 @@
     // Iterate over the elements of the API in order.  The order of appearance in the API file determines the order of
     // save & load.  This is important for sims that have order dependency between saved elements.
-    this.phetioEngine.phetioIDs.forEach( phetioID => {
+    this.phetioEngine.getPhetioIDs().forEach( phetioID => {
       const phetioObject = this.phetioEngine.phetioObjectMap[ phetioID ];
       if ( phetioObject.phetioState && !phetioObject.phetioIsArchetype ) {
Index: js/phetioEngine.js
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- js/phetioEngine.js	(revision 675b683ee10353c13d7c162beaede92a47fe6dff)
+++ js/phetioEngine.js	(date 1595978106934)
@@ -67,7 +67,7 @@
     this.phetioObjectMap = {};
     // @public (phet-io internal) {string[]} Array of all of the registered phetioIDs in the order they were registered.
-    this.phetioIDs = [];
+    // this.phetioIDs = [];
     // @private {Emitter} - Signifies when a new PhetioObject is added to PhET-iO.
     this.phetioTypesAddedEmitter = new Emitter( {
@@ -278,7 +278,7 @@
     assert && assert( !this.simConstructed, 'baselines are nulled out after sim is constructed. Call this before then.' );
     const result = {};
-    this.phetioIDs.forEach( phetioID => {
+    this.getPhetioIDs().forEach( phetioID => {
       const phetioObject = this.phetioObjectMap[ phetioID ];
       // The metadata for individual dynamic elements is not part of the API, but it's important to record this API
@@ -298,7 +298,7 @@
   getPhetioElementsMetadata() {
     const result = {};
-    this.phetioIDs.forEach( phetioID => {
+    this.getPhetioIDs().forEach( phetioID => {
       const phetioObject = this.phetioObjectMap[ phetioID ];
       // The metadata for individual dynamic elements is not part of the API, but it's important to record this API
@@ -326,7 +326,7 @@
     };
     // Iterate through all PhetioObjects and add all associated types for each.
-    this.phetioIDs.forEach( phetioID => {
+    this.getPhetioIDs().forEach( phetioID => {
       if ( !this.phetioObjectMap[ phetioID ].phetioDynamicElement ) {
         getAllRelatedTypes( this.phetioObjectMap[ phetioID ].phetioType ).forEach( addType );
       }
@@ -437,7 +437,7 @@
     this.phetioObjectMap[ phetioID ] = phetioObject;
     // Keep track of the order things were added, so changes can be applied in the same order
-    this.phetioIDs.push( phetioID );
+    // this.phetioIDs.push( phetioID );
     // After the PhetioObject construction is finished, notify listeners that it is ready for interoperability.
     timer.runOnNextFrame( () => { // eslint-disable-line bad-sim-text
@@ -527,7 +527,7 @@
    * @public (phet-io-internal) called only by phetioEngine and PhetioEngineIO
    */
   getPhetioIDs() {
-    return this.phetioIDs;
+    return Object.keys( this.phetioObjectMap );
   }
   /**
@@ -579,10 +579,10 @@
     delete this.phetioObjectMap[ phetioID ];
     // Update the array of phetioIDs
-    const index = this.phetioIDs.indexOf( phetioID );
-    if ( index > -1 ) {
-      this.phetioIDs.splice( index, 1 );
-    }
+    // const index = this.phetioIDs.indexOf( phetioID );
+    // if ( index > -1 ) {
+    //   this.phetioIDs.splice( index, 1 );
+    // }
     // push onto a stack to call at end of frame
     phetioAPIValidation.onPhetioObjectRemoved( phetioObject );

We demonstrated big performance improvements on iPad6 + Safari 13, MacBook Pro + Safari 13, and Mac Book Pro + Chrome 84. And we demonstrated that improvements for both of these bottlenecks are needed.

We decided to create issues in axon (for PropertyStateHandler) and phet-io (for phetioEngine) repos, and involve @zepumph .

@pixelzoom
Copy link
Contributor Author

pixelzoom commented Jul 28, 2020

@KatieWoe no need to do performance testing on additional platforms. There are clear bottlenecks in PhET-iO, and we'll test after they are resolved.

This issue is on hold until phetsims/axon#316 and https://github.com/phetsims/phet-io/issues/1689 are addressed.

Then I think we should have the PhET-iO team take another look to see if there are any additional PhET-iO bottlenecks that can be improved.

@pixelzoom
Copy link
Contributor Author

In #60 (comment), @samreid asked:

We pushed an improvement for phetsims/phet-io#1689, does it speed up the "Start Over" time for this test? Please reach out to me on slack to schedule a meetup time for further performance analysis.

@pixelzoom
Copy link
Contributor Author

@samreid The performance improvement in phetsims/phet-io#1689 is on my radar, and I was hoping to test performance this past week. But publishing a prototype has been given higher priority, and that prototype does not include PhET-iO. So at this point I really don't know when I'll be getting to this.

@pixelzoom
Copy link
Contributor Author

pixelzoom commented Aug 11, 2020

Testing the improvements made in phetsims/phet-io#1689 ...

Following the steps in #140 (comment), here are test results for the 5 configurations that I tested previously. I took an average of 3 runs, and I included the previous average in the table.

For brand=phet, https://phet-dev.colorado.edu/html/natural-selection/1.1.0-dev.6/phet/natural-selection_en_phet.html?showTimes&secondsPerGeneration=1:

test device OS browser times (ms) average (ms) previous average (ms)
PixelZoom - 2019 MacBook Pro macOS 10.15.6 Safari 13.1.2 64, 54, 49 56 55
PixelZoom - 2019 MacBook Pro macOS 10.15.6 Chrome 84.0.4147.125 77, 69, 64 70 76
PixelZoom - 2009 MacBook Pro macOS 10.11.6 Safari 11.1.2 197, 135, 127 153 196
PixelZoom - 2009 MacBook Pro macOS 10.11.6 Chrome 84.0.4147.125 182, 159, 126 156 156
PixelZoom - iPad6 iOS 13.6 Safari 13 94, 98, 83 92 89

For brand=phet-io, https://phet-dev.colorado.edu/html/natural-selection/1.1.0-dev.6/phet-io/natural-selection_all_phet-io.html?postMessageOnError&phetioStandalone&showTimes&secondsPerGeneration=1:

test device OS browser times (ms) average (ms) previous average (ms)
PixelZoom - 2019 MacBook Pro macOS 10.15.6 Safari 13.1.2 521, 503, 483 502 1241
PixelZoom - 2019 MacBook Pro macOS 10.15.6 Chrome 84.0.4147.125 350, 395, 399 381 873
PixelZoom - 2009 MacBook Pro macOS 10.11.6 Safari 11.1.2 1437, 1331, 1326 1365 9118
PixelZoom - 2009 MacBook Pro macOS 10.11.6 Chrome 84.0.4147.125 775, 789, 752 772 1826
PixelZoom - iPad6 iOS 13.6 Safari 13 1024, 948, 899 957 1050

As expected, brand=phet performance was about the same. brand=phet-io performance was dramatically better, and acceptable (< 1 second) on all platforms tested - with the exception of the 2009 MacBook Pro, which really isn't a supported platform.

The next step would be to have @KatieWoe test on the other platforms (especially the Lovelace Chromebook). But I don't want to incur that cost until I verify that the iO team doesn't have plans to make any other general improvements for this issue. @samreid thoughts?

@pixelzoom
Copy link
Contributor Author

But I don't want to incur that cost until I verify that the iO team doesn't have plans to make any other general improvements for this issue.

On Slack, @zepumph and @samreid identified these 2 issues as relevant, "both about removing things and unregistering constraints or listeners":

phetsims/axon#316
phetsims/axon#317

Labeling this issue as "on-hold" until those issues are addressed.

@pixelzoom pixelzoom removed their assignment Aug 11, 2020
@pixelzoom
Copy link
Contributor Author

pixelzoom commented Aug 11, 2020

A very unscientific attempt at emulating the performance of the Lovelace Chromebook test device...

I tested 1.1.0-dev.6 brand=phet-io on my fastest platform (PixelZoom - 2019 MacBook Pro, macOS 10.15.6, Chrome 84.0.4147.125) with CPU throttling set to "4x slowdown". I chose 4x (instead of 16x) because over in #60 Lovelace was ~5.6x slower than my MacBook Pro.

The average of 3 runs was 1538 ms, which would be considered unacceptable performance. And I suspect that Lovelace will be a little slower than that.

@samreid
Copy link
Member

samreid commented Aug 19, 2020

I ran this on my iPad7 with a built version, running standalone in PhET-iO brand, and ?showTimes, and it reported:

time to mate: 348ms
time to Start Over: 184ms

On a Lenovo N23 Yoga Chromebook

time to mate: 1227ms
time to Start over: 738ms

@samreid samreid removed their assignment Aug 19, 2020
@zepumph
Copy link
Member

zepumph commented Aug 19, 2020

On a build phet-io standalone off of master on an iPad7:

to go to the 6th gen: "time to mate = 547 ms"
startover: "time to Start Over = 210 ms".

second time (no refresh):
383ms
140ms

third time (no refresh):
296ms
137ms

@pixelzoom edit: So @zepumph's average is 162 ms for "Start Over".

@zepumph zepumph removed their assignment Aug 19, 2020
@pixelzoom
Copy link
Contributor Author

pixelzoom commented Aug 19, 2020

Following the testing steps in #140 (comment) with 1.1.0-dev.12 ...

For brand=phet, https://phet-dev.colorado.edu/html/natural-selection/1.1.0-dev.12/phet/natural-selection_en_phet.html?showTimes&secondsPerGeneration=1

test device OS browser times (ms) average (ms) previous average (ms)
PixelZoom - iPad6 iOS 13.6.1 Safari 13 159, 103, 88 117 92
PixelZoom - 2019 MacBook Pro macOS 10.15.6 Safari 13.1.2 63, 49, 44 52 56
PixelZoom - 2019 MacBook Pro macOS 10.15.6 Chrome 84.0.4147.135 76, 76, 65 72 70

For brand=phet-io, https://phet-dev.colorado.edu/html/natural-selection/1.1.0-dev.12/phet-io/natural-selection_all_phet-io.html?postMessageOnError&phetioStandalone&showTimes&secondsPerGeneration=1

test device OS browser times (ms) average (ms) previous average (ms)
PixelZoom - iPad6 iOS 13.6.1 Safari 13 470, 256, 154 293 957
PixelZoom - 2019 MacBook Pro macOS 10.15.6 Safari 13.1.2 100, 86, 75 87 502
PixelZoom - 2019 MacBook Pro macOS 10.15.6 Chrome 84.0.4147.135 116, 107, 102 108 381

@pixelzoom
Copy link
Contributor Author

pixelzoom commented Aug 19, 2020

So based on the tests from @samreid @zepumph and me (in the 3 comments above), it looks like "Start Over" is acceptable on those 5 devices, including @samreid's Lenovo N23 Yoga Chromebook.

Next step is to test on Lovelace Chromebook and any other test devices known to be "performance challenged". @ariel-phet what is the availability of test resources for this task?

@ariel-phet
Copy link

@pixelzoom I think we can have @phet-steele do a chromebook test. Considering the vast improvements your are seeing, I think if that test is solid, we can call it good.

@ariel-phet ariel-phet assigned phet-steele and unassigned ariel-phet Aug 19, 2020
@phet-steele
Copy link

phet-steele commented Aug 19, 2020

Following the testing steps in #140 (comment) with 1.1.0-dev.12 ...

For brand=phet, https://phet-dev.colorado.edu/html/natural-selection/1.1.0-dev.12/phet/natural-selection_en_phet.html?showTimes&secondsPerGeneration=1

test device OS browser times (ms) average (ms)
Feynman - Chromebook 13099.62.0 84.0.4147.83 Mate times : 730, 416, 400, (refreshed sim here), 830, 809, 492 613
Start Over times : 260, 261, 189, (refreshed sim here), 283, 247, 220 243

For brand=phet-io, https://phet-dev.colorado.edu/html/natural-selection/1.1.0-dev.12/phet-io/natural-selection_all_phet-io.html?postMessageOnError&phetioStandalone&showTimes&secondsPerGeneration=1

test device OS browser times (ms) average (ms)
Feynman - Chromebook 13099.62.0 84.0.4147.83 Mate times : 1188, 938, 909, (refreshed sim here), 1206, 851, 765 976
Start Over times : 612, 405, 375, (refreshed sim here), 599, 425, 363 463

"Feynman - Chromebook" used in @phet-steele's tests is an Acer CB5-312T series, Model # N16Q10, aka Acer Chromebook 13. https://www.acer.com/ac/en/AE/content/model/NX.GL4EM.002, 2.1GHz Quad-core with 13.3" screen.

@phet-steele phet-steele removed their assignment Aug 19, 2020
@pixelzoom
Copy link
Contributor Author

pixelzoom commented Aug 20, 2020

In the above commit, I made the "time to Start Over" display a permanent feature of the sim, enabled via ?showTimes. I had been planning to remove it, but it seems like this will continue to be useful in the future.

@pixelzoom
Copy link
Contributor Author

pixelzoom commented Aug 24, 2020

Over in #60 (comment), @samreid reported a 5.5% performance improvement in phetioEngine.getAllRelatedTypes for that issue. It didn't play out that way there, so I decided to see if it was relevant for "Start Over" performance.

Following the testing steps in #60 (comment) with 1.1.0-dev.14 ...

For brand=phet, https://phet-dev.colorado.edu/html/natural-selection/1.1.0-dev.14/phet/natural-selection_en_phet.html?showTimes&secondsPerGeneration=1

test device OS browser times (ms) average (ms) previous (ms)
PixelZoom - iPad6 iOS 13.6.1 Safari 13 102, 95, 91 96 117
PixelZoom - 2019 MacBook Pro macOS 10.15.6 Chrome 84.0.4147.135 72, 62, 60 65 72

For brand=phet-io, https://phet-dev.colorado.edu/html/natural-selection/1.1.0-dev.14/phet-io/natural-selection_all_phet-io.html?postMessageOnError&phetioStandalone&showTimes&secondsPerGeneration=1

test device OS browser times (ms) average (ms) previous (ms)
PixelZoom - iPad6 iOS 13.6.1 Safari 13 191, 125, 128 148 293
PixelZoom - 2019 MacBook Pro macOS 10.15.6 Chrome 84.0.4147.135 115, 109, 92 105 108

So I'm seeing a performance improvement across the board here, which I can rationalize as ~5% on macOS Chrome. Over in #60 I did not see a 5% improvement, and iO performance was significantly worse on iPad.

@samreid is the improvement made to phetioEngine.getAllRelatedTypes actually related to #60, or is it related to this issue? I'm wondering if you had these 2 issue confused.

@samreid
Copy link
Member

samreid commented Aug 24, 2020

I think getAllRelatedTypes is called during object creation, so more likely related to #60 which is about bunny creation.

@pixelzoom
Copy link
Contributor Author

pixelzoom commented Aug 24, 2020

Thanks for clarifying.

@pixelzoom
Copy link
Contributor Author

@samreid says there are no additional PhET-iO performance improvements planned.

Performance now seems acceptable to me, including on lower end devices like Chromebooks. So I think we're ready to move to the performance "sign-off" phase in #191.

@amanda-phet
Copy link
Contributor

I agree that this is acceptable for performance. Thanks for doing all of this to make it as zippy as possible!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants