dart-lang / sdk

The Dart SDK, including the VM, JS and Wasm compilers, analysis, core libraries, and more.
https://dart.dev
BSD 3-Clause "New" or "Revised" License
10.21k stars 1.57k forks source link

[dart2js] Optimize Flutter .runtimeType patterns #41761

Open rakudrama opened 4 years ago

rakudrama commented 4 years ago

b328cadaacb12fac16a1b173c48f53ac1ba1352d Added a benchmark for the canUpdate hot method:

  static bool canUpdate(Widget oldWidget, Widget newWidget) {
    return oldWidget.runtimeType == newWidget.runtimeType &&
        oldWidget.key == newWidget.key;
  }

While the new Rti is quite a bit faster that the old rti, and faster than Dart JIT VM, the benchmark on dart2js on V8 still lags AOT VM by 3-4x.

The Type instance is cached on the _Rti object.

There are several things we can do:

There are many == methods with the following pattern:

class ValueKey<T> extends LocalKey {
  const ValueKey(this.value);
  final T value;
  @override
  bool operator ==(Object other) {
    if (other.runtimeType != runtimeType) return false;
    return other is ValueKey<T> && other.value == value;
  }

class CircleBorder extends ShapeBorder {
  ...
  @override
  bool operator ==(Object other) {
    if (other.runtimeType != runtimeType)
      return false;
    return other is CircleBorder
        && other.side == side;
  }

Ideas:

The classes that override get:runtimeType are an impediment to the above ideas, especially for the argument other of == which could be anything.

mraleph commented 4 years ago

Note that we have a special optimization for x.runtimeType == y.runtimeType - implemented in f4ec20abac2286604565e9d5a6d1d744849c964d

rakudrama commented 4 years ago

@mraleph Thanks for the reference to the VM optimization. I notice in the new RuntimeType benchmarks that AOT is 7x faster than VM. What extra is AOT doing?

mraleph commented 4 years ago

The runtimeType optimization above is AOT only, I never ported it to JIT

mraleph commented 4 years ago

For JIT we only have: