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

[extension types] AOT performance worse than normal classes. #53542

Closed
modulovalue opened this issue Sep 15, 2023 · 0 comments
Closed

[extension types] AOT performance worse than normal classes. #53542

modulovalue opened this issue Sep 15, 2023 · 0 comments
Assignees
Labels
area-vm Use area-vm for VM related issues, including code coverage, and the AOT and JIT backends. P2 A bug or feature request we're likely to work on type-performance Issue relates to performance or code size

Comments

@modulovalue
Copy link
Contributor

Dart SDK version: 3.2.0-134.1.beta (beta) (Thu Sep 14 06:41:14 2023 -0700) on "macos_arm64"
> dart compile exe --enable-experiment=inline-class dispatch_bench.dart
> ./dispatch_bench.exe

Consider the second case where extension types perform worse than classes (12ms vs 70ms):

via class on class: 12ms
via extension type on class: 70ms

via class on function via closure: 52ms
via extension type on function via closure: 30ms

via class on function via const function: 52ms
via extension type on function via const function: 30ms

via class on function monomorphic: 12ms
via extension type on function monomorphic: 12ms
void main() {
  const size = 10000000;
  final datasetClass = List.generate(size, (final a) => SomeClass(foo: a));
  final datasetExtensionType = List.generate(size, (final a) => SomeExtensionType(a));
  final sw = Stopwatch();
  void measure(
    final String name,
    final void Function() fn,
  ) {
    sw.reset();
    sw.start();
    fn();
    sw.stop();
    print("$name: ${sw.elapsedMilliseconds}ms");
    
  }
  final viaClass = RunClass();
  final viaExtensionType = RunExtensionType();
  measure(
    "via class on class",
    () => viaClass.execute(datasetClass),
  );
  measure(
    "via extension type on class",
    () => viaExtensionType.execute(datasetExtensionType),
  );
  print("");
  measure(
    "via class on function via closure",
    () => run<SomeClass>(datasetClass, (final a) => a.foo),
  );
  measure(
    "via extension type on function via closure",
    () => run<SomeExtensionType>(datasetExtensionType, (final a) => a.foo),
  );
  print("");
  measure(
    "via class on function via const function",
    () => run<SomeClass>(datasetClass, SomeClass.fooSelector),
  );
  measure(
    "via extension type on function via const function",
    () => run<SomeExtensionType>(datasetExtensionType, SomeExtensionType.fooSelector),
  );
  print("");
  measure(
    "via class on function monomorphic",
    () => runClass(datasetClass),
  );
  measure(
    "via extension type on function monomorphic",
    () => runExtensionType(datasetExtensionType),
  );
}

class RunExtensionType with Run<SomeExtensionType> {
  @override
  int sum(final SomeExtensionType v) => v.foo;
}

class RunClass with Run<SomeClass> {
  @override
  int sum(final SomeClass v) => v.foo;
}

extension type SomeExtensionType(int foo) {
  static int fooSelector(
    final SomeExtensionType a,
  ) => a.foo;
}

class SomeClass {
  static int fooSelector(
    final SomeClass a,
  ) => a.foo;
  
  final int foo;

  const SomeClass({
    required this.foo,
  });
}

mixin Run<T> {
  int sum(
    final T v,
  );

  int execute(
    final List<T> tree,
  ) {
    int total = 0;
    for (final a in tree) {
      total += sum(a);
    }
    return total;
  }
}

int run<T>(
  final List<T> data,
  final int Function(T) sum,
) {
  int total = 0;
  for (final a in data) {
    total += sum(a);
  }
  return total;
}

int runClass(
  final List<SomeClass> data,
) {
  int total = 0;
  for (final a in data) {
    total += a.foo;
  }
  return total;
}

int runExtensionType(
  final List<SomeExtensionType> data,
) {
  int total = 0;
  for (final a in data) {
    total += a.foo;
  }
  return total;
}
@lrhn lrhn added type-performance Issue relates to performance or code size area-vm Use area-vm for VM related issues, including code coverage, and the AOT and JIT backends. labels Sep 17, 2023
@alexmarkov alexmarkov self-assigned this Sep 18, 2023
@a-siva a-siva added the P2 A bug or feature request we're likely to work on label Sep 18, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-vm Use area-vm for VM related issues, including code coverage, and the AOT and JIT backends. P2 A bug or feature request we're likely to work on type-performance Issue relates to performance or code size
Projects
None yet
Development

No branches or pull requests

4 participants