question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Injection on Android is slow because of getCanonicalName()

See original GitHub issue

I’m converting an existing Android project from using RoboGuice to Dagger, and to my surprise injection of a fragment is slower with Dagger by about 5%. From method tracing, it looks like the culprit is that the Class.getCanonicalName() method can be really slow, particularly when called on inner classes.

For one injection that I profiled, AndroidSupportInjection.inject() takes 1.074s of CPU time as measured in the profiler. Of that, the two calls to getCanonicalName() for the logger call take 67ms and 164ms respectively. Then the call to DispatchingAndroidInjector.inject() takes 696ms, all of which is spent inside maybeInject(). That method spends 483ms on another call to getCanonicalName(), and then finally 209ms for the generated inject() method for my fragment’s subcomponent.

This means that 66.5% of the total time for the injection was spent inside calls to getCanonicalName(). The last instance is particularly annoying, because it’s only used as a parameter to checkNotNull() and the resulting string value is only used if the injection fails and is a complete waste of time on success path.

There are a couple of ways that this time could be improved:

  • Issue #790 has already been raised to remove the logger statement, which would remove the first two calls to getCanonicalName().
  • Calls to checkNotNull() should only evaluate getCanonicalName() on Class objects if the reference being checked was actually null. All of the calls to it that pass foo.getClass().getCanonicalName() would just pass the class instance instead, and getCanonicalName() would only be called before throwing NullPointerException.

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Reactions:15
  • Comments:6 (1 by maintainers)

github_iconTop GitHub Comments

1reaction
JakeWhartoncommented, Oct 13, 2017

Using a normal if-based null check such that the exception message is only constructed inside the conditional seems like the best option to me. Then we don’t waste time on string building for an uncommon case.

On Fri, Oct 13, 2017 at 11:51 AM David P. Baker notifications@github.com wrote:

Would replacing getCanonicalName() with getName() still be a problem? Or better yet, just use the class object.

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/google/dagger/issues/819#issuecomment-336492302, or mute the thread https://github.com/notifications/unsubscribe-auth/AAEEEaC25a1SmuETkAHzmEcN-pRn9PSFks5sr4cSgaJpZM4OjBdM .

0reactions
bejibxcommented, Oct 16, 2017

Could it be because Android uses .dex format for compiled classes?

Read more comments on GitHub >

github_iconTop Results From Across the Web

Android ViewModel additional arguments - Stack Overflow
New ViewModel creation prevents method get() . Based on documentation: "Returns an existing ViewModel or creates a new one in the scope (usually ......
Read more >
Five Common Issues That Slow Down Your App - Nimbledroid
Dependency injection reduces the amount you have to code (and hence, ... about some best practices for dependency injection in Android here.
Read more >
Migrating Room databases | Android Developers
Learn to migrate databases safely using the Room Library.
Read more >
Java Reflection Example Tutorial - DigitalOcean
The list is endless and they all use java reflection because all ... getCanonicalName() returns the canonical name of the underlying class.
Read more >
Diff - platform/development - Google Git
diff --git a/emulator/tools/Android.mk b/emulator/tools/Android.mk new file ... getCanonicalName(), "Bad parser configuration for %s: %s", manifestFile.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found