Hello,
I've recently been looking through the JetStream 2 test suite, and I found a pretty interesting behavior in the
FlightPlanner benchmark. It defines a class constructor for a class named Leg as follows:
constructor(fix, location)
{
this.previous = undefined;
this.next = undefined;
this.fix = fix;
this.location = location;
this.course = 0;
this.distance = 0;
this.trueAirspeed = 0;
this.windDirection = 0;
this.windSpeed = 0;
this.heading = 0;
this.estGS = 0;
this.startFlightTiming = false;
this.stopFlightTiming = false;
this.engineConfig = EngineConfig.Cruise;
this.fuelFlow = 0;
this.distanceRemaining = 0;
this.estimatedTimeEnroute = undefined;
this.estTimeRemaining = 0;
this.estFuel = 0;
}
At a glance, this seems like good code, written following best practices: it defines all of the properties for the object, in a consistent order, with reasonable default values. However, a bunch of subclasses extend from Leg, which makes all of these stores megamorphic. I tried wrapping the contents of this constructor with "if (this.constructor === Leg)", and copying all of the property-initialization code into the leaf subclass constructors, to enforce monomorphic behavior during construction; this yielded a 17% improvement to average speed.
Of course, storing properties during construction is only part of the problem; there are also many megamorphic loads and stores of these properties elsewhere.
This seems like a pretty common case that might have come up previously, but I found nothing in a quick search through the bug tracker and v8-dev group. Have there been previous discussions, or are there existing design docs regarding faster property access when using ES6 class inheritance?
Thanks!