[ 
https://issues.apache.org/jira/browse/GROOVY-7478?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=14604803#comment-14604803
 ] 

Patrick Julien commented on GROOVY-7478:
----------------------------------------

bq.Does none of those provide what you need? 

I am using {{GroovyClassLoader}}. However in these small scripts, statements 
really, many regular expressions are used.  A significant performance penalty 
is encountered from {{InvokerHelper#findRegex}} on subsequent runs.  These 
calls to {{findRegex}} are oblique, they come from using the regex operator, 
e.g., {{/pattern here/}}, from the Groovy code.

Even after the first run, when at least each script has been executed once, 
{{InvokeHelper#findRegex}} continues to under-perform because these patterns 
are constantly re-compiled.

Each Groovy script is:

- Compiled in a class that implements an interface defined in Java
- Is properly cached, the groovy code itself is not re-compiled after the first 
run

Sticking a cache in {{InvokerHelper#findRegex}} solves the performance issue 
for subsequent runs

----

Additionally, on first run, I also see that loading classes is also 
unnecessarily slow.  This is because for each script, the same set of 
non-existing classes is retried because the map of loaded/missed classes that 
acts as a cache, the variable {{classCache}} in {{InnerLoader}}, does not 
retain its content between compilation attempts.  This behavior is triggered by 
the list of default packages to attempt.  This one might be an incorrect setup 
but I am unable to see how to do this when reading this code.

Using reflection to populate {{InnerLoader#classCache}} with the contents of 
the very first script solves the problem with the initial load.  In other 
words, from the second to last script, I use the cache of misses from compiling 
the first script.  If the map in {{InnerLoader}} was initialized from its 
parent  {{GroovyClassLoader}} and then its results propagated to the parent, it 
would be much cleaner and solve this second performance issue.


> Ability to Cache Patterns
> -------------------------
>
>                 Key: GROOVY-7478
>                 URL: https://issues.apache.org/jira/browse/GROOVY-7478
>             Project: Groovy
>          Issue Type: New Feature
>          Components: class generator
>    Affects Versions: 2.3.9, 2.4.3
>            Reporter: Patrick Julien
>            Priority: Minor
>              Labels: usertask
>
> It seems {{InvokeHelper}} cannot cache the results of {{Pattern#compile}} at 
> all when running embedded Groovy scripts.
> When this is combined with regular expressions and a somewhat large number 
> scripts, there is a very large hit to performance when these scripts need to 
> be constantly run.
> Using Java 8u40. and close to 10k scripts, the same 10k scripts are properly 
> cached and reused but {{Pattern}} objects are constantly re-compiled.
> I am using a {{ConcurrentHashMap}} from a custom implementation of 
> {{InvokeHelper}} at the moment to workaround the problem but having a 
> supported way of controlling this behavior would be welcomed.



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

Reply via email to