You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@xalan.apache.org by Scott Boag/CAM/Lotus <Sc...@lotus.com> on 2000/10/30 16:55:40 UTC

Optimizations, changes

Well, I'm back.  Sorry for being out of touch for the last week.  In
addition to ApacheCon, I had some trouble in getting to the network from
home.

During all this time, I've been a bad boy, letting Sebastien's benchmarks
against XT get to me, and working almost exclusivly on performance.  Let me
say that I know I have a number of high priority items to address,
including the trace problems, and XPath use with DocumentFragments.  I will
try to address these later today.

In addition to making some fairly massive changes in relation to
performance, I have also fed the source through JIndent (a source-code
formatter).  I was going to try and not double-up on the performance
changes and the formatting changes, but the network problems kept me from
checking the performance stuff in, and I really wanted to get the
run-through JIndent done.  The primary advantage of the JIndent run was
less the formatting, but the automatic generation of any missing javadoc
stuff.  Where-ever there are missing javadoc stuff, a NEEDSDOC tag has been
generated.  I suspect there are several thousands of these.  The goal is to
eleminate them all with reasonable documentation, so that we have complete
java documentation.  This is more than cosmetics... I think full
documentation of all parameters, member variables, and classes/interfaces
is crucial as a form of code review, and will contribute significantly to
the robustness of the code.  I'm sorry that the CVS diffs will be next to
useless for this check-in, but this is a one-time thing, and I think it
needs to be done sooner rather than later.  It also allows other's who are
using JIndent who wish to format according to the Sun standards, or
what-ever, to do this, and then format back to the Xalan standards before
checking in (please, no code-style wars... the format is based on the J++
default formatting and I think is reasonable enough, and they are now
documented in the form of the .jin file).  The .jin file is checked in
under the xml-xalan/java/src directory.  Send flames if you wish, on this
or any other subject... I'm sure I deserve a little heat.

OK, now to the important stuff.  I focused exclusivly on Sebastien's
test1.xsl, applied against dream.xml.  The reason I found this interesting
is that it did no explicit selections, and did only a few match patterns.
It is a very clean test of the core engine.  The first thing I did was
remove the serializers from the equation by making a null content handler
for the tests.  In this test, XalanJ2 was still more that twice as slow as
XT.  I then implemented the following optimizations:

1) Brought the central loop code for itterating over selections and
applying templates to a function in ElemForEach, transformSelectedNodes.
Spent a fair amount of time optimizing this loop and making it as clean as
possible.

2) Create a child iterator (not walker) for "node()" selections.  I will do
the same for "foo" selections, and "//foo" selections.

3) Change the Stree DOM to use linked references to first child and next
and previous siblings, instead of arrays for child lists.  This follows
much more naturally the way they are being accessed by the iterators,
though perhaps at some expense for space.

4) The DocumentImpl node now holds a single character array for text.  Text
nodes copy into that array, instead of each making a String object as soon
as they are created.  A string is created upon demand.  With some
transformations, this could actually mean more space taken, rather than
less, though I think the net will be a gain for most transformations.  In
the long run, the real solution is to be able to use the original array,
and not make a copy at all.  We'll be working with the Xerces folks on
this, and maybe try to push this onto the SAX standard.  Having to make a
copy of the character data is a real nasty issue with the SAX spec.   And
why-o-why doesn't Sun define a String object that can reference a character
array, instead of having to copy?

5) Stree character nodes now implement a SaxEventDispatch interface.  Xalan
asks the node if it implements this interface via the .supports method, and
then calls dispatchSaxEvent(ContentHandler ch), allowing the text node to
directly dispatch to the characters event, directly passing in the data
from the character array in the DocumentImpl.

6) transformSelectedNodes calls the dispatchSaxEvent directly when
encountering a character node that doesn't have a template defined (and
thus uses the default text template).  dispatchSaxEvent can be used in
other places in the code, but right now it's only used in
transformSelectedNodes.

7) various other finer grained optimizations, based on measurements from
Rational Visual Quantify.

By the time I was finished, if I set the transformation thread priority
down, so that thread switching is less of an issue, XalanJ2 clocked about
the same speed as XT (for this transform only).  If I set the
transformation thread at the same priority as the parse thread, it is
slightly slower, but not by much.  The price paid for the incremental
output.

Ah, now the serializer.  I looked once again at optimizing Assaf's
serializers, and despaired.  I've already done this once with XalanJ1's
serializers, which are about the same speed as XT's serialization.  Assaf's
serializers can be optimized, but I can't afford to spend three weeks to do
it right now, and with people publishing benchmarks of XalanJ2 against XT,
I'm not prepared to let the slower serialization screw everything up.
There is also a huge issue with line break normalization (more complicated
than it might seem), which I already solved in the XalanJ1 serializers.
And there are other conformance issue with Assaf's serializers.  So I've
brought back XalanJ1's serializers, with the org.apache.serializer
interface implemented, of course, and am abandoning the transitional
serializers.  Down the line we can revisit this one way or the other, but I
think it's what we should stick with for the January release.

OK, now we get to, with the transform thread priority set down, Java 1.2,
4K buffer in the serializer:

H:\s>run2 100
.
Xalan2 + Xerces
==========================
Run     took: 312
==========================
Run     took: 278
.
XT + Xerces
==========================
Run     took: 311
==========================
Run     took: 284

And with the transform thread priority set the same as the parse (main)
thread:

H:\s>run2 100
.
Xalan2 + Xerces
==========================
Run     took: 326
==========================
Run     took: 309
.
XT + Xerces
==========================
Run     took: 290
==========================
Run     took: 296

Number of output bytes is almost exactly the same for both processors, 104K
per file.

So, I'm fairly happy with these numbers for the moment.  I will stress that
this performance will not be reflected in most stylesheets... we still have
a fair amount of tuning to do in other areas not stressed by this test.
This only reflects the core engine.

Now on to my backlog of emails from last week...

(check-in to  be done shortly)

-scott




Re: Optimizations, changes

Posted by Gary L Peskin <ga...@firstech.com>.
Scott --

Glad to have you back.  You've been very busy.  Please let us know when
you're done checking stuff in and I will review my changes.  I have
several modules not checked in at the moment for (1) xml:space handling
and (2) documentfragment handling.

After you've checked in, I'll retrofit my changes into the newly checked
in modules.  Also, I made several improvements yesterday in the
extension mechansim classes.

Should we hold off with more changes while you run JIndent?  Are you
running it on the current versions of the classes which you didn't touch
or only on the classes that you did?  Will my changes from yesterday be
in the new versions of the modules or should I reimplement?

Congratulations on the performance stuff.  It sounds great.  I have some
ideas in the extension area, now that things are working, to change the
vectors into arrays.  The old stuff was using vectors all over the place
and I just kept that the way it was.  We know the lengths, however, at
the outset so we could convert these to arrays.  I know this code isn't
executed all that much compared to the core but some people use
extensions heavily and this should help them.

Gary

Re: Optimizations, changes

Posted by Joerg Henne <jo...@cogito.de>.
Scott,

Scott Boag/CAM/Lotus wrote:
> 
> Ah, now the serializer.  I looked once again at optimizing Assaf's
> serializers, and despaired.  I've already done this once with XalanJ1's
> serializers, which are about the same speed as XT's serialization.  Assaf's
> serializers can be optimized, but I can't afford to spend three weeks to do
> it right now, and with people publishing benchmarks of XalanJ2 against XT,
> I'm not prepared to let the slower serialization screw everything up.

first of all: my apologies if this is the wrong list - I don't fully
understand which project's scope the serialization API is in - xerces'
or xalan's. I have attached a message I sent to xerces-j-dev a few days
ago on which I got no followups at all. I am aware of the fact that the
patch in question covers only a tiny aspect of the serialization process
and performance optimization shoud be approached on a higher level.
However, I think that the patch might turn out to be useful somehow.

Joerg Henne