-
Notifications
You must be signed in to change notification settings - Fork 10
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
First load very slow on older hardware #57
Comments
This might be a bit tough to do. A simple unprecise time calculation of each statement in the static constructor shows
I can possibly get rid of these computations when pre-generating these values too.
which adds up to 76ms. So this will probably lead to a reduction of 60ms with the new code = 170ms time for the new initialization in the static constructor. These are alias specific
and with these we still end up with probably around 120ms just for the aliases which I don't think can be reduced anymore because the necessary emojis list call which is is the most time consuming task is required for everything and can't be left out. What Java version do you use? I noticed that when I switch from 8 to 17 the time goes from 230ms to 160ms without changing anything else. With Java 21 its around 180ms but generally a newer Java version should help a bit too. I don't know how android development works, but would it be an option to use the library once on startup in another thread to initialize it? |
Since this is Android, we don't have a classic JRE and we don't have choice over it. On Android, a runtime called ART compiles the Java code to native code, with varying degrees of optimization depending on Android version. I am seeing relatively quick load times on an Android 15 emulator (~100ms on my host machine), but slow times on an Android 7 emulator (> 1s on the same host machine).
Unfortunately that doesn't really work for us: the app in question is a GitHub client, which shows the news feed as first screen. Showing that news feed requires parsing the GitHub API response, part of which is replacing the emoji aliases. So whether we do the class initialization in the UI thread (when showing the UI for the GH event list) or in a background thread doesn't really matter because in the latter case the UI thread will need to wait for the initialization of the class anyway. The fact that speed depends on Android version in my eye hints to the compiler having issues in optimizing the initializer, similarly to what's described here. I wonder whether a lazily initialized singleton holding the required data may work better, just to avoid the static initializer? Besides that,
a 25% improvement in loading time seems quite impressive already :-) |
The largest improvement I got was by pre computing the constant variables. This got me down to about 150ms-160ms.
This is interesting. But it seem somewhat logical how it works / that it has issues. When applying the suggested fix it got probably another 10ms faster. Maybe on android the impact is even larger with no static constructors. But the biggest issue is still initializing the auto generated emojis list which stays at approximately 100ms. I think that's because 5500+ emoji objects are created. When assigning values only when they are actually used for the first time, I it took around 110ms to only initialize alias specific variables. So the difference is somewhat around 20-40ms for being fully initialize vs on demand. For now I've rewritten the code which should yield the best performance on startup which means only using alias methods takes ~110ms on my pc. Lets see how this behaves in an android environment. Version |
Great, thanks a lot for this! We'll try and let you know about the results. |
JEmoji version
1.7.0
Steps to reproduce
When running (an app using) the library on an older device, the first
EmojiManager
static method invocation takes a very long time due to that class' static initializer. On a Sony Xperia X compact times up to 2 seconds were seen - see here for details.What is expected?
Short initialization time (say < 100ms)
What is actually happening?
Very long initialization time (up to 2 seconds)
Any additional comments?
A lot of the time seems to be spent generating lookup maps for every possible use case; however, apps do typically use only a very specific subset of use cases. In our example, we only need 'replaceAliases`, so we don't need anything e.g. dealing with HTML entities. One solution therefore could be replacing the static map initialization by getter methods, initializing the static maps lazily once they're actually needed. Doing so would reduce both computing effort and memory usage in case only a subset of the library capabilities is actually needed.
The text was updated successfully, but these errors were encountered: