Closed samreid closed 1 month ago
We would like to consult with @jonathanolson for 26 minutes or so to make progress on these.
We consulted with @jonathanolson for 26 minutes, and removed unnecessary TODOs. There are 2 left and @zepumph and I know how to proceed.
I'll continue here
This patch demonstrates a savings of about 40,000 Vector2 allocations over 10 seconds of using the boat.
@jonathanolson and @zepumph and I discussed that we should make a more holistic approach to supporting mutation in Segment.ts, without just adding this to an isolated part. Here are the methods in Segment.ts that return a Vector2:
public abstract get start(): Vector2;
public abstract get end(): Vector2;
public abstract get startTangent(): Vector2;
public abstract get endTangent(): Vector2;
public abstract positionAt( t: number ): Vector2;
public abstract tangentAt( t: number ): Vector2;
We discussed that we should add an optional returnValue?:Vector2
to the latter 4 of these. However, after reviewing the implementations of other Segment subtypes, it looks like a lot of work to rewrite the arithmetic to avoid that allocation, for example, EllipticalArc:
public positionAt( t: number ): Vector2 {
return this.positionAtAngle( this.angleAt( t ) );
}
public positionAtAngle( angle: number ): Vector2 {
return this.getUnitTransform().transformPosition2( Vector2.createPolar( 1, angle ) );
}
Or in Line:
public positionAt( t: number ): Vector2 {
return this._start.plus( this._end.minus( this._start ).times( t ) );
}
So it would be odd to add a returnValue?:Vector2
parameter and still generate other garbage along the way. Also, if we continue with this, we may want to put more effort into having kite internally call the allocation-free ones. However, I saw that Line.positionAt is only called 24 times during startup of buoyancy (and not called during the runtime).
I'm also not convinced that complicating the API and implementation of all this is a good tradeoff for the performance boost in this case which can be attained in other ways. Let's chat before continuing.
I'll double check and refresh the patch above
Refreshed patch, with count/savings instrumentation:
I removed the instrumentation from the patch, and was getting ready to commit this:
Using the chrome dev tools on mac m1, I compared the before and after, and was surprised to see how little it mattered:
without the fix: 8mb teeth 7.5 teeth/sec 0% time spent in Vector2 constructor
with the fix: 8mb teeth 7.5 teeth/sec 0% time spent in Vector2 constructor
There is a chance the allocation characteristics may be different on a different platform, but from this view it may be preferable not to commit this change, since it somewhat reduces readability at the call sites.
Either way, it seems I should check in with @zepumph, so let's do that first.
Noting that no changes were committed for this issue for dev test 1.2.0-dev.4. We should decide what we want to do for RC.1.
We didn't feel like Buoyancy's usage of Vector2s in KITE were worth the time for the above changes. We saw that there were about 200000 Vector2s created in the any sim screen in about 20 seconds. We saw 10000 for the boat in about 10 seconds. If we really care about performance, let's focus on it more broadly, as there are certainly more valuable spots to work on this.
From TODOs in https://github.com/phetsims/density-buoyancy-common/issues/86