views:

64

answers:

2

I'm developing an application which uses different components to create an XHTML document, I used StringTemplate for creating the document data of the components and then combined them into a one large document. This is an example of a component:

public class BoxImpl extends AbstractContainerImpl implements Box {

    private static final StringTemplate template;

    static {
        template = new StringTemplate(
        "<div id=$id$>$content$</div>");
    }

    public BoxImpl(String id) {
        this.setId(id);
    }

    @Override
    public CharBuffer generate() {
        // Get a local instance
        StringTemplate template = BoxImpl.template.getInstanceOf();
        // Set ID attribute of box
        template.setAttribute("id", this.getId());
        // Generate view for controls inside this container
        CharBuffer inner = this.generateInner();
        // Add inner data as content attribute
        template.setAttribute("content", inner == null ? "" : inner.array());
        // Return the result
        return CharBuffer.wrap(BoxImpl.template.toString());
    }

}

My question is, is it more efficient to implement this kind of document building using XML DOM or a StringBuilder, compared to the StringTemplate?

EDIT: I do not need XML validation.

A: 

DOM is slow compared to StringBuilder. When you are using StringBuilder, make sure you initialize the size first, like this:-

StringBuilder sb = new StringBuilder(1000);

If you don't initialize the size, then you really aren't gaining whole lot of benefit using StringBuilder in the first place.

limc
+1  A: 

From a perfomance point of view I'm pretty sure DOM would be worse than your usage of StringTemplate. Using StringBuilder might be a bit faster and maybe even cleaner looking (if used implicitly):

public CharBuffer generate() {
    String content = inner == null ? "" : inner.array();
    return CharBuffer.wrap( "<div id=\"" + this.getId() + "\">" + content + "</div>" );
}

The fastest way to do this would probably be to avoid the creation of temporary strings entirely, i.e. to write directly into a BufferedOutputWriter or PrintWriter.

But in general I'd suggest to use one of the dedicated Stream Writer APIs for the creation of XML documents. There are several non obvious pitfalls when you put vanilla strings directly into a XML documents without awareness for proper escaping of special characters. These APIs usually offer also a failry efficient implementation that beats most naive approaches. Examples for such APIs are: StAX, Apache XMLIO and SAX Transformer.

x4u
I'm not sure if this has been updated in Java 6, but in previous versions I remember that multiple string concatenations would result in a new StringBuilder created for each occurrence of the '+' operator.
MikeD
It was changed from StringBuffer to StringBuilder with Java 1.5.
x4u
@MikeD In 1.4 and before, that was indeed the case. I believe I remember observing that the bytecode in 5.0 no longer used one `StringBuffer` per `+` operator.
Alan Krueger
I'd second the comment about escaping. It may seem like a minor issue, but it can be a significant problem later on, causing random problems that may only be visible in the application consuming the XML you emit.
Alan Krueger
Escaping and validation won't be a problem, I developed a similar servlet application and site was served as XHTML Strict, and validated, i handle this while class property values are set.
Deniz Acay
Now I'm using Woodstox implementation of StAX without creating temporary strings, thanks for information..
Deniz Acay