jstrachan | 22 Dec 06:37 2004

Re: Slow parsing--maybe due to class loaders?

Hi Denis

I'm sure your analysis is correct and that parsing Groovy expressions is 
much slower than it should - as currently the parser is never quite sure 
what's a class, whats a property/variable etc. So there is lots of 
redundant calls to 'is this a class' inside the parser. I'm hopeful that 
the new parser should hopefully fix that, when it gets wired in - having 
a more well defined grammar, we should hopefully limit the times we try 
to lookup some text as a class.

Fingers crossed. In the meantime we could always do more profiling?

Denis Howlett wrote:

> Hi,
> I've been using Jexl until now, but recently discovered Groovy and thought
> that this would be a much better fit for what I need.
> I've got a rule language with conditions and actions and I want each
> condition and action to be an expression. So, I've got some code that parses
> a file and creates Groovy scripts for each clause o each rule. I can then
> test the rules and fire the ones where the conditions are true.
> With Jexl, the performance is nice and quick, but the language is pretty
> limited and there are quite a few things that I can't do easily.
> With Groovy, I can do everything I need, but... I have a weird problem. I
> have a file which has 198 expressions in it. In Jexl this takes around 381
> msecs to read in and parse. In Groovy this takes 40759, so 100 times
> longer!!!! (And this is just the parsing, I don't execute the rules in the
> test.)
> Now, that's inside IntelliJ in a Junit test. I also have this inside a web
> application hosted in Tomcat (which will be the final destination). 
> In Tomcat, Jexl takes the same amount of time, but Groovy only task
> 11276secs. Around a quarter of the time.
> I know that Groove is doing (and is capable of) much more than Jexl--and
> that's why I like it. Stepping through, on the parse it seems to spend a lot
> of time trying to load classes in case they might be there, which of course
> Jexl doesn't have to do.
> So, I wondered if my code was inefficient.
> Originally I created a GroovyShell and passed in the expression, but I
> thought there might be quite a bit of set up time on that, so now have the
> following implementation of my GroovyExpression:
>     private static GroovyShell _shell = new GroovyShell();
>     private Script _script;
>     private String _expression;
>     public GroovyExpression(String expression) throws ParseException {
>         try {
>             _expression = expression;
>             _script = _shell.parse(expression);
>         } catch (Exception e) {
>             throw new ParseException("Could not parse expression <" +
> expression + ">.  Message: " + e.getMessage(), 0);
>         }
>     }
> ...
> Is there anything I could do better? (Each script is independent of the
> other one, I intend to create a binding, set the binding on the script and
> then call run() to evaluate the script.
> Thanks in advance,
> Denis