One last update for this week on the topic. It appears that MultiBindings is 
now the biggest issue left in Guice after I successfully remove all 
just-in-time bindings from our entire application (quite a task I must say). 
Here are the last of the Guice entries from my profiling hotspot list:

Key.hashCode
ConstructorInjector.construct
Errors.withSource

After some digging, it looks like all of these calls are occurring inside of 
MultiBindings. I wasn't able to completely remove MultiBindings yet, but it 
seems as though that will be the only way to get Guice out of the hotspot list. 

I'm hoping to clean out all MultiBindings this weekend or next week. I'll send 
out a final email next week with results. 

In case anyone was interested in our numbers thus far, we have managed to take 
the application from roughly 4,000/second to around 14,000/second. Not all of 
this was from Guice, but about 5,000-7,000/second of it was.

-bp

On Aug 17, 2012, at 10:06 AM, Brian Pontarelli <[email protected]> wrote:

> Just to follow up a bit more on this topic.
> 
> I removed all just-in-time bindings from our projects. After doing this, I 
> saw an additional 35%-40% bump in performance. 
> 
> I also managed to make a couple of our Multibindings singletons, which helped 
> contribute to the 35%-40% I saw.
> 
> I haven't run the profiler again yet, but I'll be doing that in a few minutes 
> and will share any new findings I come across.
> 
> -bp
> 
> 
> On Aug 16, 2012, at 10:30 AM, Stuart McCulloch <[email protected]> wrote:
> 
>> On 16 Aug 2012, at 16:01, Brian Pontarelli wrote:
>> 
>>> Although the Error object is still a large concern of mine, the 
>>> Multibindings is much larger. I have managed to reduce our use of 
>>> Multibindings considerably and this had a huge impact on performance. I got 
>>> another 5-10% boost after removing as many as I could.
>> 
>> Yes, that really needs investigating - I don't use multibindings much 
>> myself, but it really shouldn't be that expensive.
>> 
>>> As for the Error objects, we are using a lot of @ImplementedBy annotations 
>>> in our frameworks and libraries. We do this because it tends to provide 
>>> simpler overriding of interfaces in applications that use the frameworks 
>>> and libraries. I can use explicit bindings for everything and provide the 
>>> overriding ability via a module where each binding is setup in a separate 
>>> protected method. Then overrides would go in sub-classes. Not an ideal 
>>> solution, but should work.
>>> 
>>> If it would speed things up, it would be nice to be able to configure Guice 
>>> to rip through the classpath on startup and convert all just-in-time 
>>> bindings to explicit bindings. Not sure if this is possible, but could be a 
>>> nice feature.
>> 
>> You could create a module using a classpath scanner like reflections, etc. 
>> that looks for interfaces with @ImplementedBy and binds the interface to the 
>> given implementation. Then use Modules.overrides to overlay your application 
>> + extension bindings on top of these default explicit bindings. 
>> Alternatively if scanning is not an option (or would be too expensive) then 
>> you could use the Elements SPI to analyze the application bindings to find 
>> out which dependencies are unsatisfied before the injector is created and 
>> add explicit bindings for them.
>> 
>>> Lastly, is the ConstructorContext also a symptom of just-in-time bindings 
>>> as well?
>> 
>> I believe so.
>> 
>>> -bp
>>> 
>>> On Aug 16, 2012, at 3:35 AM, Stuart McCulloch <[email protected]> wrote:
>>> 
>>>> My gut feeling (given the large amount of transitory Errors instances) is 
>>>> the application is doing a lot of lookups involving just-in-time bindings, 
>>>> maybe also involving child injectors.
>>>> 
>>>> When Guice attempts a just-in-time binding it keeps track of any errors - 
>>>> when the uppermost binding fails the injector cleans up any intermediate 
>>>> stray bindings and throws the aggregate Errors instance. 
>>>> 
>>>> If I can get some spare time this weekend I'll try a frequency analysis of 
>>>> the Errors in that heap dump, this should indicate what bindings have the 
>>>> most effect and whether child injectors are involved.
>>>> 
>>>> On 15 Aug 2012, at 22:30, Brian Pontarelli wrote:
>>>> 
>>>>> I thought I would share some information I've been collecting while 
>>>>> profiling CleanSpeak. Just a quick run down on CleanSpeak to set the 
>>>>> stage:
>>>>> 
>>>>> Written entirely in Java
>>>>> Uses Prime MVC
>>>>> The test we setup was to our main WebService entry point
>>>>> This test simulates handling real-time chat inside games
>>>>> This is usually between 1,000-30,000 messages per second depending on the 
>>>>> game
>>>>> CleanSpeak is currently able to handle 4,000-10,000 messages per second 
>>>>> on a single server (we are working to get that higher though)
>>>>> Using a custom built load test system to simulate 10-100 clients hitting 
>>>>> the WebService
>>>>> Using NetBeans profiler for timing metrics
>>>>> 
>>>>> Based on the time profiling information we are getting from NetBeans, 
>>>>> here are the top classes and the percentage of the processing time that 
>>>>> they consume (full disclosure - I remove 3 of our classes from this list):
>>>>> 
>>>>> com.google.inject.multibindings.MapBinder$RealMapBinder$2.get()   
>>>>> 6.557378%
>>>>> com.google.inject.internal.InternalContext.getConstructionContext(Object) 
>>>>> 3.3661668%
>>>>> com.google.inject.internal.Errors.withSource(Object)      3.2637234%
>>>>> freemarker.core.Environment.process()     2.9239252%
>>>>> com.google.inject.internal.InjectorImpl$4.get()   2.7241063%
>>>>> com.google.inject.internal.ConstructorInjector.construct(com.google.inject.internal.Errors,
>>>>>  com.google.inject.internal.InternalContext, Class, boolean)   2.472883%
>>>>> org.primeframework.mvc.parameter.el.DefaultExpressionEvaluator.getValue(String,
>>>>>  Object)   2.457187%
>>>>> org.primeframework.mvc.parameter.el.ExpressionException.<init>(String)    
>>>>> 2.3623912%
>>>>> com.google.inject.internal.cglib.reflect.$FastConstructor.newInstance(Object[])
>>>>>    2.3241668%
>>>>> org.primeframework.mvc.workflow.RequestBodyWorkflow.perform(org.primeframework.mvc.workflow.WorkflowChain)
>>>>>         2.286451%
>>>>> org.primeframework.mvc.servlet.ServletObjectsHolder.getServletRequest()   
>>>>> 2.0882587%
>>>>> org.primeframework.mvc.parameter.el.MemberAccessor.getAnnotation(Class)   
>>>>> 2.08238%3077
>>>>> 
>>>>> I left off everything below 2% use. The interesting things I've found 
>>>>> here are that Multibindings appears to be quite expensive. I'm going to 
>>>>> try and remove that use to see if I can get back that 6%. I also found 
>>>>> that Error object that I wrote about in a previous post near the top at 
>>>>> 3.26%. This seems to be quite expensive for an Error object, specifically 
>>>>> when Guice errors are almost always found and fixed at test time and not 
>>>>> in production.
>>>>> 
>>>>> Has anyone else seen these types of performance results and have good 
>>>>> insight into helping reduce them?
>>>>> 
>>>>> -bp
>>>>> 
>>>>> -- 
>>>>> You received this message because you are subscribed to the Google Groups 
>>>>> "google-guice" group.
>>>>> To post to this group, send email to [email protected].
>>>>> To unsubscribe from this group, send email to 
>>>>> [email protected].
>>>>> For more options, visit this group at 
>>>>> http://groups.google.com/group/google-guice?hl=en.
>>>> 
>>>> 
>>>> -- 
>>>> You received this message because you are subscribed to the Google Groups 
>>>> "google-guice" group.
>>>> To post to this group, send email to [email protected].
>>>> To unsubscribe from this group, send email to 
>>>> [email protected].
>>>> For more options, visit this group at 
>>>> http://groups.google.com/group/google-guice?hl=en.
>>> 
>>> 
>>> -- 
>>> You received this message because you are subscribed to the Google Groups 
>>> "google-guice" group.
>>> To post to this group, send email to [email protected].
>>> To unsubscribe from this group, send email to 
>>> [email protected].
>>> For more options, visit this group at 
>>> http://groups.google.com/group/google-guice?hl=en.
>> 
>> 
>> -- 
>> You received this message because you are subscribed to the Google Groups 
>> "google-guice" group.
>> To post to this group, send email to [email protected].
>> To unsubscribe from this group, send email to 
>> [email protected].
>> For more options, visit this group at 
>> http://groups.google.com/group/google-guice?hl=en.
> 

-- 
You received this message because you are subscribed to the Google Groups 
"google-guice" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/google-guice?hl=en.

Reply via email to