Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

General Guice performance guidelines

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.

like image 266
thebamaman Avatar asked Apr 03 '13 18:04

thebamaman


People also ask

Does Google use Guice?

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.

Does Guice use reflection?

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.

What is @inject annotation in 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.

Why is Guice useful?

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.


1 Answers

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:

  1. 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.

  2. 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.

  3. 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.

like image 94
toadzky Avatar answered Sep 28 '22 00:09

toadzky