Skip to Content.
Sympa Menu

xom-interest - Re: [XOM-interest] More parsing performance patches

xom-interest AT lists.ibiblio.org

Subject: XOM API for Processing XML with Java

List archive

Chronological Thread  
  • From: Wolfgang Hoschek <whoschek AT lbl.gov>
  • To: Elliotte Harold <elharo AT metalab.unc.edu>
  • Cc: xom-interest AT lists.ibiblio.org
  • Subject: Re: [XOM-interest] More parsing performance patches
  • Date: Sat, 23 Jul 2005 11:02:32 -0700

On Jul 23, 2005, at 4:58 AM, Elliotte Harold wrote:


Michael Kay wrote:


Another case to consider is where the events are coming from the output of
an XSLT transformation, where it's quite likely that each <xsl:value-of>
instruction or piece of literal text in the stylesheet will lead to a call
on characters().



Good point. XOM uses a completely different class (nu.xom.xslt.XSLTHandler) for such events, though, so none of the changes made where will have any effect on that, one way or the other. I did make the Vector-->ArrayList switch Wolfgang suggested in that class too. I have not changed its buffering behavior though.

Hmm, are there any other classes where something other than a real XML parser is likely to be feeding data into XOM? Probably, but I can't think of any off the top of my head. Still, the possibility that someone is using a funky filter that calls characters() in a pattern quite different from what you'd expect in an XML parser does suggest that Wolfgang is right and XOMHandler should use a StringBuffer for multiple calls to characters. I'll put that on the TODO list.



There's still a small inaccuracy in what you committed that leads to a memory leak on JDK 1.4 (but not JDK 1.5) with the "fat" Text, if there are exactly two calls to characters():

Consider that new StringBuffer(String) allocates 16 bytes of extra memory on the second call to characters(), on the grounds that more chars are to be added later (why else would one make a StringBuffer from a String?). Later, when flushText() retrieves a buffer.toString () you get a String that shares the char[] array with the Stringbuffer. Thus the XOM Text object subsequently created will hold a string that consumes more memory than necessary (up to 16 *2 bytes).

The reason it's not a leak on JDK 1.5 it that StringBuffer.toString() returns a compacted char[] *copy*, rather than a shared backing array.

The algorithm I proposed takes that into account, and allocates a StringBuffer with the exact required capacity on the second character () call. It works equally well on JDK 1.4 and 1.5. Two calls to characters() are rare, but not that rare to make this a non-issue.

[Yet another case why there's a reason why the algorithm I proposed is formulated the way it is. If you deviate from the proposal, make sure to consider the subtle details that implies.]






Archive powered by MHonArc 2.6.24.

Top of Page