|
|
Re: Overhead and Best Practices: msg#00021
java.ikvm.devel
|
Subject: |
Re: Overhead and Best Practices |
We are typically doing the following:
try {
return _expression_.evaluate( tuple,
handle,
this.declaration,
this.requiredDeclarations,
workingMemory );
} catch ( Exception e ) {
throw new RuntimeDroolsException( e );
}
and
try {
KnowledgeHelper knowledgeHelper = new org.drools.base.DefaultKnowledgeHelper( activation,
workingMemory );
activation.getRule().getConsequence().evaluate( knowledgeHelper,
this.workingMemory );
} catch ( Exception e ) {
throw new ConsequenceException( e,
activation.getRule() );
}
Where ConsequenceException is runtime. As these two are called
repeatedly I'd be interested to know the impact on standard java a well
as IKVM and .net
Mark
Jeroen Frijters wrote:
Michael Kay wrote:
Mind you, I was surprised to discover recently that the overhead is in
creating the exception, not in throwing it.
Ah yes, good point. It's actually a bit more complicated than that. If
you use the "throw new Exception" idiom, the stack trace is not created
at that point, but only when the exception is "caught" either by a
finally block or a handler that uses the exception object. Note that for
some exception types (related to the remapping of exception type that
occurs) the overhead is always present (this is something that could be
improved).
Here's an example of relatively efficient exception code:
try
{
throw new FileNotFoundException();
}
catch (FileNotFoundException _)
{
// don't touch the exception
}
10,000 iterations takes 120 ms on IKVM vs 40 ms on JDK 1.5
Changing the code only slightly:
try
{
FileNotFoundException x = new FileNotFoundException();
throw x;
}
catch (FileNotFoundException _)
{
// don't touch the exception
}
Now 10,000 iterations take almost 6 seconds!
However (and this really sucks and should be fixed) the following code
also runs slowly:
try
{
try
{
throw new FileNotFoundException();
}
finally
{
// do something trivial to prevent the finally block from being
optimized away
x++;
}
}
catch (FileNotFoundException _)
{
// don't touch the exception
}
With respect to the remapped exception taking longer, the following is
also slow (and should be fixed):
try
{
throw new FileNotFoundException();
}
catch (Exception _)
{
// don't touch the exception
}
BTW, the primary reason that the first case is optimized is because of
the way class loading works in Java, each class load typically involves
multiple thrown ClassNotFoundException exceptions and because of that
this optimization is very important to make class loading a little less
inefficient. This change shaved a very significant amount of time off
the startup time of Eclipse.
Regards,
Jeroen
|
| |