Performance Differences (Java and C#)

108 views
Skip to first unread message

Raz Friman

unread,
Jun 23, 2015, 3:27:58 PM6/23/15
to antlr-di...@googlegroups.com
Should there be any performance differences between the current Java and C# ANTLR Runtimes? (4.5/4.5.1) Or are there any optimizations made to the Java runtime?

I am running into an issue where when there are many nested if/else statements (~100+).

When I try to parse this program on the C# runtime it took 10 minutes.
However, when run through the Java runtime this process takes less than 1 second!!

If this seems like a real issue, I will try to create a set of files that can reproduce this behavior and let you guys see for yourselves.


Just to clarify, I am working with the latest runtimes released on the ANTLR.org website (4.5).


Thanks,

Raz

 

Terence Parr

unread,
Jun 23, 2015, 4:46:38 PM6/23/15
to antlr-di...@googlegroups.com
Hiya. could easily be some differences. can you run a profiler? It might be in a hash function for ATNConfigSet or DFAState.

Ter
--
You received this message because you are subscribed to the Google Groups "antlr-discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to antlr-discussi...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Raz Friman

unread,
Jun 24, 2015, 9:43:55 AM6/24/15
to antlr-di...@googlegroups.com
I will take a look at those functions.

I attached a CSV with the profiler data from the C# runtime.
It seems like the functions taking the most time are (Highest exclusive % and time):
Antlr4.Runtime.Atn.PredictionContextCache.IdentityCommutativePredictionContextOperands.Equals(object)

System.Collections.Generic.IDictionary`2.TryGetValue(!0,!1&)

Antlr4.Runtime.Atn.ParserATNSimulator.Closure(class Antlr4.Runtime.Atn.ATNConfig,class Antlr4.Runtime.Atn.ATNConfigSet,class Antlr4.Runtime.Atn.ATNConfigSet,class System.Collections.Generic.HashSet`1<class Antlr4.Runtime.Atn.ATNConfig>,bool,bool,class Antlr4.Runtime.Atn.PredictionContextCache,int32,bool)

SlowCSharpProfiler.csv

Eric Vergnaud

unread,
Jun 25, 2015, 12:56:02 PM6/25/15
to antlr-di...@googlegroups.com
Hi,

could you also provide profiler data for the Java version (for the same input file)?
it would help to understand the differences

Eric 

Terence Parr

unread,
Jun 25, 2015, 1:59:30 PM6/25/15
to antlr-di...@googlegroups.com
That all looks to be in hashing and equivalents for hash tables.  We had totweak the hash functions quite a bit to get that working efficiently in Java.
T

Raz Friman

unread,
Jun 25, 2015, 3:45:16 PM6/25/15
to antlr-di...@googlegroups.com
I shortened and reduced my the grammar affecting the file mentioned above and found that 1 parser rule was causing the Slowdown/Hanging in C#.
I have included fully working examples in both Java and C# that replicate this issue.

In JAVA, both the "Slow" and "Fast" grammars run in less than a second
However, in C# the "Slow" grammar does not finish at all and throws a StackOverflow Exception, while the "Fast version finished in 350ms.

I marked which rule is causing this issue for C# in the slow grammar file.

procedure_division:
             PROCEDURE DIVISION DOT sentence* paragraph* section* #ProcedureDivisionWithSections
           | PROCEDURE DIVISION DOT sentence* paragraph*          #ProcedureDivisionWithOutSections
           ;

If this rule is changed to:
procedure_division:
            PROCEDURE DIVISION DOT sentence* paragraph* section* #ProcedureDivisionWithSections
            ;
Then C# is able to parse through the file successfully.

I hope this is useful to determine the cause of the error,


AntlrIssue.zip

Sam Harwell

unread,
Jun 26, 2015, 11:50:03 AM6/26/15
to antlr-di...@googlegroups.com
I'm not at a computer where I can test this (but I will ASAP). I noticed this strange bit:

section* #ProcedureDivisionWithSections


I'm curious what happens if you use section+ here instead of section*. In the current form, the second alternative will never be used. 

Sam

Sent from my Verizon Wireless 4G LTE smartphone

Raz Friman

unread,
Jun 26, 2015, 12:05:10 PM6/26/15
to antlr-di...@googlegroups.com
I tried modifying the rule and have the same results. This is just a stripped down example of the grammar that I was able to create the reproduces the issue.
procedure_division: 
              PROCEDURE DIVISION DOT /* extra stuff here */ sentence* paragraph* section+ #ProcedureDivisionWithSections
            | PROCEDURE DIVISION DOT /* other stuff here */  sentence* paragraph+  #ProcedureDivisionWithOutSections
            ;




Thank you for looking into it. I tried it to make it as easy as possible to debug with a fully compilable example in both C# and Java in the attached ZIP file from my previous post

Eric Vergnaud

unread,
Jun 27, 2015, 10:11:56 PM6/27/15
to antlr-di...@googlegroups.com
Hi Raz,

I don't have the full context, but I notice the following:
 - In the slow version below, the only difference between the 2 alternatives is optional sections.
 - In other words, sections are forbidden for the second alternative and optional in the first one.
 - Practically, the first alternative already covers all cases. 
 - So the fast version, which equals the slow version minus the second alternative, covers all cases too.
Can you not use the fast version and check for the absence of sections in your listener?

Eric  
Reply all
Reply to author
Forward
0 new messages