12 Replies Latest reply on May 14, 2008 10:01 AM by toby.tobias.hill.gmail.com

    Seam Performance Optimization

    www.supernovasoftware.com

      After speaking with Norman Richards at the latest HJBug, I tried a performance tip he suggested.


      I was using the following SFSB to color some rows in my datatbable.



      @Stateful
      @Name("pipeSearchFormat2")
      @Scope(ScopeType.EVENT)
      public class PipeSearchFormat2Bean implements Serializable, PipeSearchFormat {
      
        @In(required = false)
        private Map pipeSummary;  
        
        public String getRowColor()
        { 
      
          Long stateId = (Long) pipeSummary.get("stateId");
           Date dateAvailable = (Date) pipeSummary.get("dateAvailable");
          Date date = new Date();
          
          if(stateId==0) 
               return "green";
          if(dateAvailable!=null && date.getTime()>dateAvailable.getTime()) 
               return "red";
          return "";
        }
       
        @Remove @Destroy
        public void destroy() { }
      
      }
      



      He mentioned in his presentation how interceptors could slow down your code if used incorrectly.


      I switched the code to the following and immediately obtained a 75% performance boost for that view.


      @Name("pipeSearchFormat")
      @Scope(ScopeType.EVENT)
      @BypassInterceptors
      public class PipeSearchFormatBean implements Serializable 
      {     
           public String getRowColor() 
           {
                Map pipeSummary = (Map) Component.getInstance("pipeSummary");
                Long stateId = (Long) pipeSummary.get("stateId");
                Date dateAvailable = (Date) pipeSummary.get("dateAvailable");
                Date date = new Date();
      
                if (stateId == 0)
                     return "green";
                if (dateAvailable != null && date.getTime() > dateAvailable.getTime())
                     return "red";
                return "";
           }
      }




      The only changes are making it a plain POJO, adding @BypassInterceptors, and looking up the variable manually.


      The performance increase was actually more.  I had made the scroller only page 15 rows because of the slow rendering.


      Now I can render 50 in less time than it took to render 15 before.


      Thanks Norman.

        • 1. Re: Seam Performance Optimization
          damianharvey.damianharvey.gmail.com

          Thanks Jason. There isn't much information on @BypassInterceptors in the docs.


          a) When should this annotation be used?


          b) When shouldn't it be used?


          I assume that any sort of Helper class should get this annotation - especially where it is pretty much self-contained. Whereas any class that acts as a controller should not have it especially if it needs to inject/outject more than a few components from/to the context.


          Can Norman/Pete/etc provide some guidance around this as the performance increase is too tempting to ignore.


          Thanks,


          Damian.

          • 2. Re: Seam Performance Optimization
            nickarls

            I am sure the upcoming performance review that has been mentioned will also result in better docs on that part.


            I haven't followed the performance threads that closely but I got the impression that the injection happens on every call; does that also mean that if you have a FooBean with n injections and FooBean has a FooEntity and you have a page with m references to the entity, every fooBean.fooEntity.fooField getter call also results in the n fooBean injections?


            Some sort of @In(lazy=true) would be cool but I guess it's not possible since it hasn't been done.

            • 3. Re: Seam Performance Optimization
              bolke

              Am I way off in expecting this would normally be solved in the presentation layer (eg. the xhtml file) by exposing the necessary variables in the row variable?

              • 4. Re: Seam Performance Optimization
                techieexchange1

                Hi Folks,


                I just came across a blog entry on Seam Performance and its interesting.


                Here's the link:
                http://svetzal.wordpress.com/2008/03/02/performance-profiling-with-jboss-seam-part-1/

                • 5. Re: Seam Performance Optimization
                  fernando_jmt

                  Hi Jason,


                  I think the increment of performance is due to the change you did from @Stateful to simple POJO component, more than removing @BypassInterceptors.


                  After reading your post I was wondering what would be the impact of my code, which is very similar to yours:


                  @Name("cipherUtil")
                  @BypassInterceptors
                  @Scope(ScopeType.EVENT)
                  public class CipherUtil {
                       public encrypt(String text) {
                            return ((Cipher) Component.getInstance("cipher")).encrypt(String.valueOf(value));
                      }
                       ...
                       
                  }
                  
                  



                  To the following:


                  @Name("cipherUtil")
                  @Scope(ScopeType.EVENT)
                  public class CipherUtil {
                  
                      @In
                      private Cipher cipher;
                  
                       public encrypt(String text) {
                            return cipher.encrypt(String.valueOf(value));
                      }
                       ....
                  }
                  



                  I tested it several times, and I get the similar response time (78ms) for 10 items.


                  The xhtml is:


                   <rich:dataTable value="#{categoryList.resultList}" var="categoryItem" id="categoryListId"
                                          rows="10"
                                          width="100%">
                              <rich:column>
                                  <f:facet name="header">
                                 Code     
                                  </f:facet>
                                  <h:outputText value="#{cipherUtil.encrypt(categoryItem.code)}"/>
                              </rich:column>
                   </rich:dataTable>
                   



                  I didn't try to test changing it to an @Stateful, but I guess that could be the reason.


                  I think it would be a pain to get rid of @In or @Out to increase performance and to have to use Component.getInstance() otherwise.


                  Anyway, I'm looking forward to the Seam performance recommendations.


                  • 6. Re: Seam Performance Optimization
                    www.supernovasoftware.com

                    I tested it again to verify.


                    I removed @BypassInterceptors and injected my variable.


                    The page load was then avg 3.6 sec.


                    After adding @BypassInterceptors back and looking up manually, it dropped back to avg 1.7 sec.


                    There reason in my case it that I am calling this simple POJO once for every cell in the table.  50 rows X 20 columns causes 1000 calls to this component in one page.


                    This is why I see the dramatic increase.  I would think this would cause a similar performance problem if I had 1000 users accessing a  page that only called it once.


                    For this simple usage, I have no problem using


                    Component.getInstance



                    instead of


                    @In


                    • 7. Re: Seam Performance Optimization

                      Jason Long wrote on Mar 03, 2008 06:41 PM:


                      For this simple usage, I have no problem using

                      Component.getInstance



                      instead of

                      @In





                      While this might be the case. It is still a workaround rather than a solution, don't you agree?


                      Do you know by chance whether there is a JIRA issue for this (I couldn't find one)?

                      • 8. Re: Seam Performance Optimization
                        christian.bauer

                        This is on our radar already, see .


                        • 9. Re: Seam Performance Optimization
                          brachie

                          Hi,


                          and instead of


                          @Out
                          private MyTest test;
                          



                          I should use:



                          Contexts.getConversationContext().set("test", test);
                          



                          ?

                          • 10. Re: Seam Performance Optimization
                            brachie

                            Hi,


                            while


                            @In
                            EntityManager entityManager
                            



                            works for me, unfortunately the following returns null in my case...


                            EntityManager em = (EntityManager) Component.getInstance("entityManager")
                            



                            the same with the Seam log-component.
                            Why is null returned?



                            Alexander

                            • 11. Re: Seam Performance Optimization

                              Christian Bauer wrote on Mar 03, 2008 08:04 PM:


                              This is on our radar already, see .



                              This is excellent! But I actually meant something more traceable (JBSEAM-2704) :)

                              • 12. Re: Seam Performance Optimization
                                toby.tobias.hill.gmail.com

                                Here is a related thread: http://www.seamframework.org/Community/SeamPerformanceProblemRewardingWorkaround.


                                That discussion lands in a DTO-pattern for avoiding the repeated injection-overheads. It also provides some tools for finding similar problems over the set of beans (pojos or SxSB) you have in your application.