Replies: 4 comments 1 reply
-
Interesting observation Peter. The current runtime has no optimization applied so far, as it had first to work like the JS runtime before and I want to have the runtime tests in TS, before I start improving it. That change for the For the story A better replacement might be the immutable.js library (which I used in jree), as their containers use object equality too (they use the term |
Beta Was this translation helpful? Give feedback.
-
I just did a quick check with your proposed changes in the benchmarks and found almost no improvement:
So for these parse runs the HashSet change has not much impact. Do you have an explanation or idea why it is so heavy in your test cases? OK, the cold start is faster, but that's not relevant here, as this is a one time task. More important is what happens once the runtime is warm. |
Beta Was this translation helpful? Give feedback.
-
Interesting, I used a Java like grammar. I'll have to validate my observations. It must be a combination of the grammar and input files that triggers the excessive calls to I actually just now noticed I've used the original Antlr4 runtime in my tests. In your fork you have removed the For the next few days I don't have my laptop, I'll have to revalidatie my observations next year to get some more insights. |
Beta Was this translation helpful? Give feedback.
-
I forked the
As you can see get length() {
return Object.keys(this.data).map((key) => { // 600:39
return this.data[key].length;
}, this).reduce((accumulator, item) => { // 602:21
return accumulator + item;
}, 0);
} The culprit seems to be
Which uses the length of the HashSet as stateNumber: const newState = proposed;
newState.stateNumber = dfa.states.length;
configs.setReadonly(true); Note that I had to run as CommonJS module due to my project being CommonJS without an option to switch at this moment due to a number of dependencies breaking |
Beta Was this translation helpful? Give feedback.
-
I've done some performance analysis on the JS implementation of
antlr4
using nodejs as I wasn't very happy with the performance.Parsing and lexing 2000 files took about 130-150 seconds. Some individual source files were taking up to 15-20 seconds per file.
I couldn't really figure out why the parsing was much slower than I expected, tried to tune the grammar file among some other things. Finally I hooked up a basic node.js profile using
--prof
and to my surprise the theget length()
property of theHashSet
class was on top of the list.Looking at the implementation the
HashSet
class, and especially thelength
-property the code very inefficient.Replacing the
length
-property with a simple field that is incremented when an new (unique) item is added into the set made a huge difference. Parsing and lexing time went down to just 25 seconds which is almost an 80% improvement.The performance improvement is beyond my expectations, my grammar and the state of the source files probably is related but nonetheless I think it is worthwhile to have a look at the HashSet and HashMap implementation and if possible replace them with their native JS counterparts Set and Map.
Either way just wanted to share my observation :)
Snippet:
Beta Was this translation helpful? Give feedback.
All reactions