You can find the full source code for this website in the Seam package in the directory /examples/wiki. It is licensed under the LGPL.
| Online: | 29 Members of 3614 |
| Forum: Seam Users |
01. Mar 2008, 00:25 CET | Link |
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.
12 Replies: | |||
|---|---|---|---|
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. |
|||
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. If a man speaks in the forest and there is no woman around to hear him, is he still wrong? |
|||
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? |
|||
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/ |
|||
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. |
|||
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. Fer © |
|||
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
Thank you for your time, |
|||
Jason Long wrote on Mar 03, 2008 06:41 PM: 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)? Regards, Siarhei |
|||
This is on our radar already, see Tuning the Seam website. Check out my weblog or have a look at the books I wrote. |
|||
Christian Bauer wrote on Mar 03, 2008 08:04 PM: This is excellent! But I actually meant something more traceable (JBSEAM-2704) :) Regards, Siarhei |
|||
Hi, and instead of @Out private MyTest test; I should use:
Contexts.getConversationContext().set("test", test);
? |
|||
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 |
Thank you for your time,
Jason Long
CEO and Chief Software Engineer
BS Physics, MS Chemical Engineering
http://www.ocgtsoftware.com
HJBUG Founder and President
http://www.hjbug.com