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.

Reply via email to