groovy-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Goo Mail <>
Subject Groovy parser very slow when using ImportCustomizers
Date Fri, 20 Nov 2015 20:05:57 GMT
Hi all,

I am using Groovy embedded into an application which runs user-provided
scripts. I see a significant parsing performance issue when the compiler is
configured to add ~30 automatic imports via an ImportCustomizer, but I
can't figure out why it is happening.

For various unrelated reasons, we segregate individual user scripts by
creating a new GroovyClassLoader for each one and parsing each script in
its own context. (These classloaders all chain to a single parent Groovy
classloader that contains some shared functionality.)

With the scripts segregated like this, I noticed that even an empty script
takes 300+ ms to parse, which seems excessive. If I remove the automatic
imports, the parse takes <10 ms instead. But I also found something bizarre
in how the CompilerConfiguration seems to influence the parse time.

I am 99% sure that the parsed class is not cached, since I turned off all
of those options and I also stepped into the parse() function to confirm
that it was walking through all of the phases.

Could it be that the extra time is actually consumed by loading/resolving
the imported classes, and not something Groovy is manipulating during the
parse itself? That seems possible (and is potentially understandable, at
least on the first invocation), except for one weirdness:

The parse time problem appears tied to the specific instance of a
CompilerConfiguration object being provided to the child classloader. For
example, when creating the child classloader, if I supply the same
CompilerConfiguration object that was provided to the parent classloader,
the parse time suddenly get very fast!

But if I instead construct a new CompilerConfiguration object for every
script, the parse is very slow, even though the newly-constructed CC is
identical to the previous one, and even though each script is still using
its own separate classloader.

What is going on (and how do I fix it)? Here is an example that you can run
in groovysh that demonstrates the problem:

Here is the output:

===> true
Showing slow parse time
Parse time: 281 ms
Parse time: 260 ms
Parse time: 280 ms
Parse time: 277 ms
Parse time: 259 ms
Parse time: 257 ms
Parse time: 279 ms
Parse time: 260 ms
Parse time: 278 ms
Parse time: 282 ms
===> null
Showing fast parse time
Parse time: 280 ms
Parse time: 3 ms
Parse time: 3 ms
Parse time: 2 ms
Parse time: 3 ms
Parse time: 2 ms
Parse time: 2 ms
Parse time: 3 ms
Parse time: 3 ms
Parse time: 2 ms
===> null

Thanks for any insight you can provide!

- Scott

View raw message