I have code with performance issues using closures accessing private fields:
@CompileStatic
class X {
private Y a,b,c
void blah() {
doClosureThing { //This gets run in a loop, 1000s of times
a = ...
b = ...
c = ...
}}}
When profiling, I see the majority of time is spent in
ScriptBytecodeAdapter.setGroovyObjectProperty. Looking at the bytecode, I see
the closure is setting X variables a,b,c via this method, which essentially
delegates to a reflection-based set: "getThisObject().setProperty("a", value)".
I notice that the read references to a, b, c use a generated method like
"pfaccess$1" to actually read the values.
Is this expected behavior for static compiler?
If I create setters for the fields, the closure bytecode references the setters
directly (although there is an awkward ScriptBytecodeAdapter.castToType of
getThisObject instead of a normal cast), and the speedup is about 10x for my
code (70ms to 6ms).
This is in performance-sensitive code and we use this pattern in a lot of
classes to execute small pieces of business logic on 1000s+ items. Any
recommendations on how to improve without requiring changes other than in the
shared doClosureThing method? One thing I am about to try is changing my
methods like doClosureThing from a Closure to an abstract class, trying to
replicate the behavior I get with delegates by manually creating non-abstract
methods that delegate to the original closure's delegate, but it is a lot of
work and I'm not even sure if it will do anything.
Jason Winnebeck
Software Engineer III Contractor - IT Software Development | Windstream
600 Willowbrook Office Park, Rochester, NY 14450
[email protected]<mailto:[email protected]> |
windstreambusiness.com
o: 585.794-4585
----------------------------------------------------------------------
This email message and any attachments are for the sole use of the intended
recipient(s). Any unauthorized review, use, disclosure or distribution is
prohibited. If you are not the intended recipient, please contact the sender by
reply email and destroy all copies of the original message and any attachments.