-
Notifications
You must be signed in to change notification settings - Fork 1.5k
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
VM: 25% of dart2js run time in MegamorphicLookup #26017
Comments
Apart from making megamorphic calls faster in the VM: Is there any way to avoid some of these megamorphic call sites in dart2js? - They will always be slower than monomorphic calls. |
Note that this strongly impacts the dartanalyzer and the analysis server as well. Between those three tools, it impacts the lives of every Dart developer every day in some way or another. As I understand it, at least one source of these megamorphic call sites is as follows. Design a class hierarchy in which a method defined at the root of the hierarchy is overridden in a large enough number of subclasses, then write a general method that can, and does, take an instance of any class in that hierarchy and invoke this method. (By the way, how many implementations of a method does it take to make it megamorphic?) If that's true, then, yes, there might be a way of avoiding some of them, but only by writing worse code. Support for polymorphism is near the heart of what it means to be an object-oriented language with inheritance. Anything you can do to improve the performance of these cases would benefit every developer every day. |
@fsc8000 I can get rid of some of them by copying methods from mixins and base classes to the classes containing definitions of the other members used by the method. Consider:
Once ListMixin is used above some number of times, with some clients defining isEmpty, |
I can help categorize cases of MegamorphicLookup: [A]. Calls from a method in a base class to a method that is defined on one or more derived classes. [C]. Overgeneralization. (This is what Brian describes)
None of the dozen or so subclasses of C declares anything called foo. Given that p.foo is monomorphic, the initial compilation should have widened the receiver check as much as possible and prevented the deoptimization. In dart2js, [D] Calling get:hashCode and ==. An example that combines [A] and [D] is using small integers as hash table keys.
If the VM had cloned Object.hashCode into _Smi, Object.hashCode@_Smi could be optimized by inlining _Smi._identityHashCode. |
dartfmt (third_party/pkg_tested/dart_style/bin/format.dart) has some interesting case. dartfmt spends 28% of Dart time in MegamorphicLookup. @munificent 10% of the time is in MegamorphicLookup for get:hashCode. This is issue [D]. There is a closure that calls MegamorphicLookup accounting for 5% of total Dart time.
There is a 'Rule' hierarchy of 7 classes There is a default implementation of get splitsOnInnerRules => true and and one override (2 classes) that returns an adjacently declared field. These two implementations are inlined when outer has only three classes are known, but the code gets deoptimized and five classes causes a megamorphic lookup. |
More details about the MegamorphicLookup in dartfmt, at .splitsOnInnerRules.
There are 5 classes in the ICData and megamorphic cache (one class is not instantiated, one class is abstract).
The |
Thanks. The issue with :: classes should be easily addressable. In this case though there would still be a hole in the range because of MetaDataRule. We'd need to expand the set of cids using CHA to make it a 100% dense range. btw: My CL (f6c19ee) brought time spent megamorphic lookup for |
The improvement with f6c19ee on dartfmt is around 5%. Time before and after my change:
|
See also #26858 |
Run dart2js on a large program with this command:
At isolate exit, get the cpu profile, sort by Tags: VM > User
75% of time is spend in "Dart"
Of this time, 34% is in "Type Inference"
Of this time, 31% is in [Stub] MegamorphicLookup
This seems like an excessive overhead.
@a-siva
The text was updated successfully, but these errors were encountered: