On Sep 20, 2005, at 17:40, Matthew L Daniel wrote:
Hi Matthew,
The least this would do is avoid a number of unnecessary calls to
instanceof.
You're on the right track, and maybe that "switch" impl would be an
80/20 win over the cost of the Right Way. But that huge if-instance
case
is exactly what the Visitor pattern was created to solve.
Yep! My remark was completely focused on that isolated part in one of
the +600 source files. It just seemed like the more elegant way to deal
with it --since the FONodes all have that getNameId() method, it makes
more sense to call that once and compare the resulting int value to the
constants, rather than checking the class for one node possibly so many
times.
(Plus: using 'switch' offers the benefit of having fall-through cases,
where you would need 'if-instanceof||instanceof||instanceof...')
As a personal note: I'd even like to replace all string-comparisons of
the form 'fo.getName().equals("fo:something")' in the FOTree with
'fo.getNameId() == FO_SOMETHING'. Not sure if that would save us much,
but every little bit helps I guess. Even if both strings are
internalized, 'int == int' outperforms 'String.equals(String)' by a
significant factor (and that's still leaving small things like
"fo:instream-foreign-object" [=26 Bytes] vs. FO_INSTREAM_FOREIGN_OBJECT
[=4 Bytes] out of the picture)
'instanceof' itself can IMO only be put to good use in case of a
complex class-hierarchy, where you can check for supertypes that each
have lots-and-lots of subtypes, so 'x instanceof supertype' covers ten
or more subtypes in one go.
Our FOTree isn't exactly suited for that kind of thing. Practically all
the FOs are direct subclasses of FObj, and those that aren't, have at
most one intermediate class in between...
(I've taken the liberty of adding one especially for the table-related
FOs, since they share some functionality --still have to take a closer
look at which members can be moved upward to TableFObj. For now, it's
restricted to a few methods for dealing with the column-numbering and
the border-precedences, but I'm almost certain that more can be made to
follow.)
I haven't spent enough time with the Fop codebase to speak to the
gains of such a
thing, but I'd bet RTFHandler isn't the only one that does this.
Indeed not. FYI: FOP once did use the Visitor pattern for the
layout-engine (over a year ago), but it was decided upon back then to
remove it completely, mainly for reasons of keeping the code
comprehensible for potential future committers IIRC.
A braindead `grep instanceof | wc -l` search shows 122 classes out of
the
640 classes use instanceof, which in my world makes them at least worth
examination.
Depends a bit on *what* exactly they're checking and how many times
they actually do that. If it's simple checks for FONode subtypes that
are executed lots of times, these are indeed most likely suboptimal...
Another "implied" win to the Visitor interface is if a new FONode type
gets added, it forces the change to ripple (unless the impl is using
the
DefaultVisitor) to all those who would need to handle the new
functionality.
... which indeed becomes of very much use once you start talking about
FO Extension-elements.
Thanks for the valuable feedback --and for being one of our
guinea-pigs, of course ;-)
Cheers,
Andreas