-
Notifications
You must be signed in to change notification settings - Fork 1.7k
[extension types] extension types slower than classes on AOT. #53572
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
Comments
//cc @alexmarkov |
This is not a fair comparison: extension type is erased to an 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 datasetInt = List.generate(size, (final a) => 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();
final viaInt = RunInt();
measure(
"via class • on class with instantiated mixin",
() => viaClass.execute(datasetClass),
);
measure(
"via extension type • on class with instantiated mixin",
() => viaExtensionType.execute(datasetExtensionType),
);
measure(
"via int • on class with instantiated mixin",
() => viaInt.execute(datasetInt),
);
}
class RunExtensionType with Run<SomeExtensionType> {
@override
int sum(final SomeExtensionType v) => v.foo;
}
class RunInt with Run<int> {
@override
int sum(int v) => v;
}
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;
}
} After inlining, this micro-benchmark effectively reduces to a calculation a sum of elements of a list. So this benchmark shows that holding As far as I can see this example works as expected, so closing the issue. |
@alexmarkov thank you for looking into this. The point of this benchmark was to validate the following hypothesis: Values wrapped in an extension type are always "faster" than values wrapped in a class. This doesn't seem to be the case, but it has nothing to do with extension types as I can confirm that extension types are as fast an plain integers on my machine. I apologize for the false alarm! |
Consider how an extension type is slower than a plain old class on AOT (7ms vs 9ms) in the micro benchmark at the bottom of this issue description.
I expected extension types to be at least as fast as classes, but not slower.
Note: the build that this ran on includes the following fix #53542 (comment), however, extension types appear to still be slower than a plain old class.
AOT
JIT
The text was updated successfully, but these errors were encountered: