On Mon, 2004-05-10 at 17:37, Simon Kitching wrote:
> On Sun, 2004-05-09 at 06:16, matthew.hawthorne wrote:

[logging suggestion involving reflection]

> > 
> > Is this reasonable, or too much work?
> 
> Unfortunately, I think the delegation step is just too much overhead.
> The log4j docs describe how much effort they went to to make calls fast
> in the case where the message is not logged. But commons-logging adds
> overhead to every call, and as far as I can see this approach would add
> another level of calls, including **reflection** which has significant
> overheads. 
> 
> The approach I suggest only uses Method.invoke within the getLog method.
> 
> This solution is definitely "cleaner", as it avoids having multiple
> copies of the Log and LogSource class in multiple libraries. However by
> hiding the o.a.c.l.Log interface behing a {component}.Log interface I
> believe this forces indirect invocation (Method.invoke) on every
> debug/info/warn/error call (filtered or not) which seems unacceptable to
> me. If I've misunderstood you, please set me straight..
> 
> Maybe a bytecode generation implementation of this idea would work, ie
> have a factory that generates custom classes to bridge between the local
> component's Log interface and the commons-logging Log interface. But
> that's a serious project!
> 
> I seem to remember sun introducing a class recently into the std
> libraries which uses bytecode generation to create classes on the fly; I
> think it was intended for use in swing apps to avoid too many anonymous
> inner class declarations. Anyone remember what it was? [I'm not thinking
> of java.lang.reflect.Proxy].


I've found the class I was trying to remember about. I was thinking of
java.beans.EventHandler, which was added in java 1.4 as part of the
"long term persistence" project. Unfortunately, it's just a wrapper
around java.lang.reflect.Proxy, so still uses reflection on one side
even though it generates bytecode to implement the appropriate
interface. Quite appropriate performance for GUI tasks, I think, but not
what I would look for in a logging library (see below).


On re-reading my earlier email, I thought I really should justify my
assumption that Method.invoke is too slow. So I created a test which
disables logging at info level, then logs 1,000,000 info messages
directly and via a wrapper that uses Method.invoke (note that
Class.findMethod is only used once, and the Method object cached).

Result: direct 80 msecs, indirect: 440 msecs.

So the Method.invoke wrapper makes the call around 5 times slower. I'm
not generally an optimise-at-all-costs guy, but this does sound a hefty
price to pay for breaking the explicit lib dependency.


Regards,

Simon


---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to