I currently have a command-line tool that uses Guice and its extensions fairly heavily.
After completing the functionality of the tool, I've determined that the performance is sub-standard, and started profiling using simple hprof.
This has pointed out that just creating the Injector is a significant performance problem. I generally avoid doing any real work in Modules, and reserve compute intensive work for Providers...
With that given, what are some general performance guidelines for Guice? Should I avoid using @AssistedInject and FactoryModuleBuilders? Avoid @Singletons if possible? Ensure that all bindings are explicit and avoid JIT bindings?
I've searched all over, but can't really find much addressing basic Guice performance other than people saying it's really fast.
Use of Google Guice for implementing dependency injection in application is very easy and it does it beautifully. It's used in Google APIs so we can assume that it's highly tested and reliable code.
Guice uses reflection quite heavily. Reflection on the desktop/server JVM is very efficient, and even very large Guice applications don't have performance problems related to Guice.
@Target(value={METHOD,CONSTRUCTOR,FIELD}) @Retention(value=RUNTIME) @Documented public @interface Inject. Annotates members of your implementation class (constructors, methods and fields) into which the Injector should inject values. The Injector fulfills injection requests for: Every instance it constructs.
The low level advantage of using Google Guice is a matter of cohesion in your application, your classes in the project can be loosely coupled between each other. I can provide a class for another class without them being dependent to each other.
First off, your question leaves a lot to be desired. What is "sub-standard" performance and how did you decide what that means? It is arbitrary? Do you have a user who thinks it's too slow? Does it take to long to start or too long to produce results from user interaction?
Without actual code to evaluate, it's hard to debug performance issues. Here are some tips from my experience:
Only create the injector once. I saw a project where they were creating an injector for every REST request and it had horrible performance. When they stopped doing that, their API got 15x faster. If you NEED to create multiple injectors through your code, I would strongly suggest refactoring so you don't need to.
Singletons can be great for performance, just don't misuse it. They are only created once, which can happen as soon as you create your injector (eager singletons) or when they are first requested by something else in the object graph.
Understand that Guice is a reflection based library and reflection is ALWAYS slow. Guice does an excellent job of being very fast at runtime, at the expense of a lot of reflection when you create an injector (see item 1). If you are seeing noticeable lag in your application, it probably means you are doing something wrong.
Lastly, if you decide that you just can't handle Guice's performance "issues", you could try out an alternative like Dagger from Square (version 1) and Google (version 2). It uses code generation instead of reflection so you don't have the reflection cost, but it's not as full featured and doesn't have the extensions.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With