[libxml++] Reduce overhead of unhandled SAX events



G'day all, bit of a long one this, sorry ...

I've submitted a patch to SF that allows a derived SaxHandler to specify
which events to handle, so when the default libxml2 implementation is
suitable there is no additional overhead.

Currently each SAX event handled by the xmlpp::SaxParser class has an
overhead of calling the static callback function and the virtual handler
function.  If a user doesn't care about a particular event and doesn't
override the relevant virtual function they still pay the overhead for
the two functions, and then fall back to the libxml2 implementation.
This adds two function calls to the C library equivalent, only one of
which could be inlined in most cases (the non-virtual one). This goes
against the C++ philosophy of not paying for features you don't use
(and gives ammo to those who say C++ is inherently inefficient, grrr!)

This isn't a big deal at the moment, as the events that libxml++ can
handle are the common ones that most people will override in their
derived parser, but if more events were supported (e.g. entityDecl,
resolveEntity etc.) all users of the base class would have the
additional overhead for these events, despite the fact that the
libxml2 implementation is fine for most people.

The patch adds a protected constructor taking an xmlSAXHandler struct.
The new constructor initialises _sax_handler with the supplied struct,
allowing the derived class to specify which callbacks should be enabled
(for a derived class to do this the callbacks must be protected).  For
now all this does is let a derived class specify that certain events
shouldn't be handled, however as new events are supported by libxml++
and relevant callbacks and virtual functions added this extra ctor
becomes more useful.  The new handlers could be disabled by default, but
a derived class can enable them using the new ctor.  This allows you to 
provide handlers for every event supported by libxml2, with no
additional overhead for the events you don't use (actually, I think the
vtable will be slightly larger, so there's a slight space overhead for
each additional virtual function).

Alternatively, rather than adding new functions to the base class an
extended ExtSaxParser class could add new callbacks and virtuals to the
base class, and assign them to the xmlSAXHandler that is passed to the
base ctor. This would keep the base class simple, using subtypes for
extensions (although since there's no overhaed I'd prefer to extend the
base class by adding the functions there and disabling them by default)

The downside, as I see it, is that we're exposing implementation detail
by making the callback functions visible to derived classes.

All comments welcome,

jon


-- 
"If you can't say anything good about someone, sit right here by me."
	- Alice Roosevelt Longworth




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]