14 Replies Latest reply on Jul 24, 2007 4:31 PM by Gavin King

    Seam performance concerns

    Dan Liu Apprentice

      We did a performance test on Seam using Load Runner. The result is really disappointing. Compare with our old system(Struts based), seam is about 10 times slower. Here is the result:

      Hardware: Xeon 5130 * 2 + Intel S5000 SAS + 4G 667 FBM + 15K 73G SAS RAID 10

      New seam based version (using ejb3):
      Environment: Seam 1.2.1 + ajax4jsf 1.1 + Myfaces 1.1.3 +
      Fedora Core 6 + Oracle 10g
      Test Result: 40 Transactions per second, 280 Hits per second

      Old Struts based version:
      Environment: Struts + Hibernate +
      Fedora Core 6 + Oracle 10g
      Test Result: 420 Transactions per second, 2940 Hits per second

      Our system has about 150 entity beans, 100 ejbs and involves a lot of complicated logics. When our app was small, I didn't see that much difference in performance. but with time and our app becomes large, the test result is really surprising.

      It could be that our new app is poorly written that makes it slow. having looked at jprofile result, I didn't see any bottleneck in our app. I still can't make a conclusion at this stage.

      Is there an article talking about how to improve seam performance? In Yuan's Seam book, it mentioned a few ways to improve performance like reduce logging, server-side states saving... I've tried all of them but still can't get much performance gain.

      We are in the stage of trying to improve performance as much as we can before deliver our product to our customers. Any advice would be helpful to us. Thanks.

        • 1. Re: Seam performance concerns
          mgrouch Expert

          Can you change JSF setting to 'server' side state saving (in web.xml) and try the tests again? With myfaces and these suggestions

          http://wiki.apache.org/myfaces/Performance

          it had dramatic effect.

          I haven't tried with Sun's JSF 1.2, but client side state saving should have negative impact on performance.

          Are you using facelets?

          • 2. Re: Seam performance concerns
            mgrouch Expert

            Another thing:

            JSF doesn't (in base components) let you to define a variable on a page.
            So people quite often would write something like

            #{hashMapBean[key].prop}

            in many places on the page, which in fact leads to looking up hashMap many times + using reflection to access property.

            JSF also has several (6) stages of processing the question and it operates on
            a tree of JSF components on these stages which also slowing things down.

            • 3. Re: Seam performance concerns
              mgrouch Expert

              And in your case you should migrate to MyFaces 1.1.5 and Tomahawk 1.1.6.
              MyFaces 1.1.3 is too broken anyway to be used in production.
              It would be interesting to compare Myfaces 1.1.5 performance
              vs Sun's JSF 1.2 (with server side state for both) and see who wins...


              • 4. Re: Seam performance concerns
                Dan Liu Apprentice

                Thanks for your reply. I am using server side states saving, and we don't have hashmap lookup in our pages.

                We can't migrate to MyFaces 1.1.5 and Tomahawk 1.1.6 due to compatibility problem with seam 1.2.1. Also, MyFaces 1.1.5 doesn't work well with Seam 1.3. So basically we can't change our environment just yet. Sad!

                • 5. Re: Seam performance concerns
                  mgrouch Expert

                  Have you trieed Sun's JSF 1.2? Seam 1.3.0.A is pretty good and 1.3.0 should be out soon... You also should use facelets instead of JSPs.
                  Tomahawk immediate="true" helps a bit too on forms where you do not need validation. Hibernate caching should be used. Reduce number of complicated
                  EL expressions per page (cause they are evaluated using reflexion). Use AJAX, bit not over do it (for things which can be done purely on client side you should do it on client side). Use client side validation if you can.
                  Try to find out with http://facestrace.sourceforge.net/
                  which phase takes longest and try to improve it. Profiling should give better picture.
                  Reduce logging and IO.
                  Use java StringBuilder instead of StringBuffer. Minimize string concatenation,
                  and improve other string manipulations.





                  • 6. Re: Seam performance concerns
                    mgrouch Expert

                    And local EJB interfaces vs remote ones to reduce serialization.

                    • 7. Re: Seam performance concerns
                      mgrouch Expert

                      And more ideas: Native IO on app server, JRockit JVM. Give JVM higher memory settings. Use factories for stateless objects such as DAOs (so they are created once and not repeteadly created/destroyed).

                      • 8. Re: Seam performance concerns
                        mgrouch Expert

                        Try using one transaction per page load (preferably with one EJB call in case of CMT). You might have to use wrapper transfer objects (which are considered not necessary nowadays) to wrap entities of different types.
                        This made big difference in my case. Do not forget to cache JNDI lookups.

                        See also other people experience here:

                        http://www.jboss.com/index.html?module=bb&op=viewtopic&t=105674

                        • 9. Re: Seam performance concerns
                          Stuart Robertson Novice

                          I think you would want to run your app with a profiler and find out, empirically, where your app is spending its time. I think most commercial profilers have trial versions, and there are a variety of ways to do this.

                          Your app design based on Seam/JSF is no doubt quite different than it was with Struts. I suspect that when you compare two very well designed apps built with Seam and Struts, the Seam app will be somewhat slower. But not 10x. That sounds like an application issue. Beware of blindly trying things that "might improve performance."

                          • 10. Re: Seam performance concerns
                            Stuart Robertson Novice

                             

                            "mgrouch" wrote:
                            Use factories for stateless objects such as DAOs (so they are created once and not repeteadly created/destroyed).

                            ...
                            Do not forget to cache JNDI lookups.


                            Again, you can certainly spend time doing this kind of stuff on the off chance that it will improve performance. More likely you'll find that in modern JVMs, object creation for short lived objects is essentially free, and JNDI lookups (btw, you're using Seam, right? Where are you directly interacting with JNDI anyway?) aren't going to be significant.

                            Spend some time with a profiler an find out what's going on. It's irrefutable, and will show you where you should spend effort optimizing. You may find that there are performance issues with Seam. You'll also find that if you can clearly show the issue, the Seam team will be extremely responsive in addressing these.

                            • 11. Re: Seam performance concerns
                              Chris Lowe Apprentice

                              What are your config values for Ajax4Jsf's 'forceparse' in web.xml and Seam 'debug' in components.xml: <core:init debug="false" >?

                              I believe that by default, every request is routed through a Tidy filter, even for non-Ajax pages. forceparse = false will ensure that only Ajax requests go through the tidy process.

                              Make sure debug = false as Seam will reload pages.xml and other resources on each page request which on my machine adds 50ms or so to each request.

                              Between the struts and seam scenarios I assume you are using the identical JVM versions/parameters?

                              • 12. Re: Seam performance concerns
                                mgrouch Expert

                                How do I set ajax4jsf forceparser to false with Seam 2.0?
                                There used to be ajax4jsf filter but not anymore.
                                I want to disable ajax4jsf tidying up output on each request.

                                With older Seam version I could do this...

                                + <filter>
                                + <display-name>Ajax4jsf Filter</display-name>
                                + <filter-name>ajax4jsf</filter-name>
                                + <filter-class>org.ajax4jsf.Filter</filter-class>
                                + <init-param>
                                + <param-name>forceparser</param-name>
                                + <param-value>false</param-value>
                                + </init-param>
                                + </filter>
                                



                                • 13. Re: Seam performance concerns
                                  Thomas Gerhards Newbie

                                  @mgrouch:
                                  How do you cache JNDI lookups?

                                  I only have this in my components.xml. What would I have to add? Thanks!

                                  <core:init
                                   jndi-pattern="nmp/#{ejbName}/local"
                                   debug="true"/>


                                  • 14. Re: Seam performance concerns
                                    Gavin King Master

                                    Look at web-2.0.xsd