Monday, July 21, 2008

The results of the first part of profiling SC

The found problems from user perspective were:
1. slow sip-communicator loading
2. graphics slow loading
3. large chat history slow processing

The starting up of the sip-communicator is slow enough, it takes about 10 - 15 seconds. SC uses apache felix for loading up the bundles, it takes up to 330 milliseconds for every bundle to start up. Other time for starting up is going to the drawing swing/awt components and loading up images. When profiling the functionality I just see Felix and JDK methods invocations, it is up profiling JDK and Felix, their methods are time-consumptive.Very similar situation was with big chat history slow processing.

The slowest part is the text parsing with javax.swing.text.html.HTMLFactory (see net.java.sip.communicator.impl.gui.utils.SIPCommHTMLEditorKit's inner class HTMLFactoryX).
There are two ways for eliminating the problem:
- wait for updated and more optimized java version
- to profile jdk
- to use other technology for text formating

Then I just monitored the sip-communicator with a profile to search for anomalies (took the 10 most expensive methods). I found that processSmilies() method from ChattConversationPanel class class is also consumpitve with big texts, thist uses regular expressions for smilies finding and the regular expression is very complex for it.

I noticed that net.java.sip.communicator.util.ScLogFormatter is also time-consumptive, it takes about 2-3% of sip-communicator execution. The problems are format(LogRecord record) and inferCaller(LogRecord record) methods. First is using DecimalFormat for formatting is required time to process and also sending the messages to the output. The second is using StackTraceElement objects and processings, that are time consumptive.
These methods are made with help of JDK and those are not very effective.There are Thread.sleep's in sip-comm code which are look like performance problems in profiler (look in net.java.sip.communicator.plugin.statusupdate.StatusUpdateActivator or just search for .sleep in sip-comm's source, you will found some), is the value of the sleeping time correct ?
There are minor time problems that are also connected with libraries that are slow.

Notes for developers.
What I can suggest to community is to continue adhere design patterns. Also quite effective is not to return a new created object, but reuse an already existing one - a creation of an object take more time and makes the heap larger. Of course it is not often possible, for example in net.java.sip.communicator.impl.gui.utils.SIPCommHTMLEditorKit inner class HTMLFactoryX.

static class HTMLFactoryX extends HTMLFactory
implements ViewFactory {
public View create(Element elem) {
View v = super.create(elem);
if(v instanceof ImageView){
return new SIPCommImageView(elem);
} else if (v instanceof ParagraphView) {
return new ParagraphViewX(elem);
}
return v;
}
}

Namely View is created by create(Element element) method from javax.swing.text.html.HTMLFactory class, the Element object is necessary for the new instance of view, and there is no possible to clean up and return existing View class. But if we see the createDefaultDocument() in c class, we see that HTMLDocument doc variable can be reused - there is no in parameter for the object:

public Document createDefaultDocument() {
if(doc != null) return doc;
StyleSheet styles = getStyleSheet();
StyleSheet ss = new StyleSheet();
ss.addStyleSheet(styles);
doc = new HTMLDocument(ss);
doc.setParser(getParser());
doc.setAsynchronousLoadPriority(4);
doc.setTokenThreshold(100);
return doc;
}

Also I reused the creation of new SIPCommHTMLEditorKit classes in ChatConversationPanel. Actually the fix is not very helpful, because the method createDefaultDocument() is called only once from ChatConversationPanel but the same logic you can use in your projects.

Next Steps for SC profiling:
1. Profile and fix increasing threads problem
2. Look for memory leaks using different profilers

1 comment:

Richard said...

I wonder in your startup costs for Felix are you counting the time it takes to install the bundles or to install AND start the bundles? The installation aspect is definitely related to Felix costs, but starting bundles is not really related to Felix necessarily, since the cost of bundles that perform long activities in their activators is from the bundles themselves not Felix.

I have not looked at the bundles, though, so I don't really know if they perform long actions in their activators or not. In general, bundles should do as little as possible in their activators, with any long tasks done in a background thread.

Just some thoughts on narrowing down from where the costs come.