NativeScript / android

NativeScript for Android using v8
https://docs.nativescript.org/guide/android-marshalling
Apache License 2.0
530 stars 135 forks source link

Improve performance of generating JS class from Metadata #1824

Open ammarahm-ed opened 1 month ago

ammarahm-ed commented 1 month ago

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?

  1. 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.
  2. We don't eagerly load Inner type members like android.R.integer. For example accessing android.R.integer only loads methods, properties on android.R & android.R.integer and any base classes. Previously it would load all classes in android.R then load your class android.R.integer which would take 100s of ms!
  3. In java you can have method overloads, to tackle this the current runtime stores method information in a std::unordered_map and 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 used robin_hood::unordered_map that 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.