Improve performance of generating JS class from Metadata
Java classes can have 100s and even thousands of methods and properties on them, for example android.view.View has 673 methods on it, similarly android.R class has always been slow to access since it has many nested classes. A common issue that many of us have faced and tried to workaround in various ways using metadata filtering and other hacks. But it doesn't properly fix the problem, even classes that have a few methods, take too long to load the first time. This can have affect on TTI, navigating to new pages that access a java class my many methods because everything is running on UI thread.
This PR tries to fix the issue once and for all, loading classes is now super fast. Almost as fast as the iOS runtime. But how?
- Classes will still load all their properties and methods eagerly like before but we avoid loading metadata information we don't need like the method name, signature, return type etc etc for methods. When you call a java method the first time, that information is loaded and cached for further calls.
- We don't eagerly load Inner type members like
android.R.integer. For example accessingandroid.R.integeronly loads methods, properties onandroid.R&android.R.integerand any base classes. Previously it would load all classes inandroid.Rthen load your classandroid.R.integerwhich would take 100s of ms! - In java you can have method overloads, to tackle this the current runtime stores method information in a
std::unordered_mapand for every method it adds to the prototype, it will check whether there is existing method information of a method with same name. This is fine for small classes but when class is huge, the lookup becomes quite slow. To fix this we have usedrobin_hood::unordered_mapthat results in great performance gain.
There are still places that could see improvement but as of now with theses changes, most classes will load in 0.1-0.2ms.
This is a big change and is spread across multiple files.