Visitor performance

47 views
Skip to first unread message

Alexey Pomelov

unread,
Nov 14, 2018, 7:38:24 AM11/14/18
to antlr-discussion
Hello.

I need to parse some expression and then evaluate it multiple times against some context (say, list of variable values).

I created an Expression class based on the string representation of the expression. The constructor creates a lexer, a parser, and extracts the root ExpressionContext to a class field.
After that, some 'eval' method creates a new EvalVisitor and run visitExpression method against the root expression context.

I have this kind of rule in the grammar:

    expression : conjunction (OR conjunction)* ;

and it's being processed by this method in the EvalVisitor:

    @Override
    public Boolean visitExpression(ExpressionContext ctx) {
        for (ConjunctionContext conjunction : ctx.conjunction()) {
            if (visitConjunction(conjunction)) return true;
        }
        return false;
    }

The problem is ctx.conjunction() method each time calls ParserRuleContext.getRuleContexts(Class), that iterates children and creates a new list.
So, in fact, my visitor creates almost a copy of the AST on each call. Profiling shows that 90% CPU time I spend in getRuleContext and getRuleContexts methods.

Rough caching into Map<ExpressionContext, List<ConjunctionContext>> on the Expression class level gives about 7 times performance boost. Seems if I cache all context retrieval methods I'll get 10-20 times boost.
But this approach seems not very elegant to me. As an alternative, I can create my own domain model, build it with a visitor and then use it for all other purposes.

Which approach is the correct one? Maybe something third?

Thanks!

Fred Curts

unread,
Nov 14, 2018, 7:43:49 AM11/14/18
to antlr-discussion
If you replace `conjunction` with `cs+=conjunction` in your grammar (twice), `ctx.cs` will be a List<ConjunctionContext> that's only created once.

Alexey Pomelov

unread,
Nov 14, 2018, 12:02:52 PM11/14/18
to antlr-discussion
Wow, it was so simple. And the same effect I get with usual (non-collection) labels. Haven't known about them enough yet.

Thanks a lot, Fred, you've made my day!)

среда, 14 ноября 2018 г., 14:43:49 UTC+2 пользователь Fred Curts написал:
Reply all
Reply to author
Forward
0 new messages