-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
[AOT/perf] classes holding an int can be more efficient than plain integers? #53594
Comments
It seems unlikely that this benchmark can measure a significant difference in the access of the integer. The overhead of multiple function calls is so much larger than the thing being measured, that any difference in inlining or optimization will completely drown out the possible signal. When I compile this code (only multiplying
It's consistent that If I add the following two lines at the end of Object o = datasetClass.first;
if (o is! SomeClass) throw "Bad"; (as an attempt to check that all instances of
If I change those lines to T confuse<T>(T v1, T v2) =>
DateTime.now().millisecondsSinceEpoch > 0 ? v1 : v2;
Object o = confuse(datasetClass.first, datasetExtensionType.first);
if (o is! SomeClass) throw "Bad"; (to really check that
Whatever this thing is timing, it's has about a factor of two of uncertainty. It's as if the more I look at In any case, this doesn't so much show that class access is faster than extension type access, more that also doing class member access may slow down direct access. That's also interesting. |
This gave me the idea to try the following: When I run the code in the issue description repeatedly, I get 15ms for the I'm not sure what to make of this (is this a bug? is this considered expected behavior?), but it is confusing and counterintuitive to me from the perspective of a user. I expected AOT to be more consistent when it comes to performance or at least not to have code that comes after some code slow down (or speed up?) code that comes before it. This is similar to #53571 where the use of some feature appears to slow down unrelated parts of the program. |
Micro.-benchmarks are generally not particularly good at measuring optimizing compilers. If 99% of your programs runtime is on the same piece of code, a 5% deviation seems significant. |
@lrhn Is there any other strategy that you can recommend that would allow one to develop a better intuition for how to write performant Dart programs running on the VM? Even if micro benchmarks are imperfect, I'm hoping that it's better than completely relying on my intuition. I agree that it's suboptimal, but they can be useful! |
I'd write real programs, then see where their bottlenecks are. I'll always go for avoiding allocation, and avoiding copying. And avoiding unnecessary work or overhead in general. |
/cc @alexmarkov |
Dart VM (both JIT and AOT) uses 2 different representations for integers: tagged (when int value can be potentially mixed with other objects, e.g. put in a container such as List) and unboxed. Tagged representation is compatible with other instances. It also avoids instance (box) creation when value is small (Smi), at the cost of an extra bit test when loading a value. That is not measured in your micro-benchmark, but equally important. What you see in this micro-benchmark is a small overhead of loading a value from a tagged representation compared to loading a field with unboxed representation. It works as intended. If you would like to achieve maximum performance, avoid using integers as objects and use specialized lists from |
(cf. #53572 (comment))
It can be shown that a program (running on the VM AOT) using a class that holds an integer can perform better than the same program using an integer without a wrapper class.
This can lead to counterintuitive results where a class can perform better than an extension type (cf. #53572)
I'm wondering, could "integers" perform as well as a "class holding an integer"? Or is there a reason why that might not be possible, desired, or worth the effort?
micro-benchmark as a repro
dart compile exe --enable-experiment=inline-class dispatch_bench4.dart
./dispatch_bench4.dart
The text was updated successfully, but these errors were encountered: