From: Jonathan W. <co...@co...> - 2003-02-20 18:27:06
|
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 |