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.
