Skip to content

Commit

Permalink
More Functional APIs for the parsing DSL.
Browse files Browse the repository at this point in the history
relates to #324

* Includes some performance Optimizations for *_SEP DSL methods.
* Includes updates for performance guidelines docs.
  • Loading branch information
bd82 committed Dec 11, 2016
1 parent 4a4d4bf commit 847f5ad
Show file tree
Hide file tree
Showing 7 changed files with 404 additions and 168 deletions.
2 changes: 1 addition & 1 deletion benchmark/parsers/cssDevParser.js
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,6 @@ function CssParser(input) {

// medium [ COMMA S* medium]*
this.media_list = this.RULE('media_list', function() {
$.SUBRULE($.medium)
$.MANY_SEP(Comma, function() {
$.SUBRULE2($.medium)
})
Expand Down Expand Up @@ -313,6 +312,7 @@ function CssParser(input) {
// selector [ ',' S* selector ]*
// '{' S* declaration? [ ';' S* declaration? ]* '}' S*
this.ruleset = this.RULE('ruleset', function() {
// TODO: try without SEP?
$.AT_LEAST_ONE_SEP(Comma, function() {
$.SUBRULE($.selector)
})
Expand Down
1 change: 0 additions & 1 deletion benchmark/parsers/cssOldParser.js
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,6 @@ function CssParser(input) {

// medium [ COMMA S* medium]*
this.media_list = this.RULE('media_list', function() {
$.SUBRULE($.medium)
$.MANY_SEP(Comma, function() {
$.SUBRULE2($.medium)
})
Expand Down
56 changes: 53 additions & 3 deletions docs/faq.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,10 @@ See [related documentation](../examples/parser/minification/README.md) for detai

### <a name="PERFORMANCE"></a> How do I Maximize my parser's performance?

#### Major Performance Benefits

These are highly recommended for each and every parser.

1. **Do not create a new Parser instance for each new input**.

Instead re-use a single instance and reset its state between iterations. For example:
Expand Down Expand Up @@ -118,8 +122,12 @@ See [related documentation](../examples/parser/minification/README.md) for detai
2. **Choose the optimal Token Type for your use case.**

See [Token Types Docs](docs/token_types.md) for more details.

3. **Avoid creating parsing rules which only parse a single Terminal.**

#### Minor Performance Benefits

These are only required if you are trying to squeeze every tiny bit of performance out of your parser.

1. **Avoid creating parsing rules which only parse a single Terminal.**

There is a certain fixed overhead for the invocation of each parsing rule.
Normally there is no reason to pay it for a Rule which only consumes a single Terminal.
Expand All @@ -132,5 +140,47 @@ See [related documentation](../examples/parser/minification/README.md) for detai
```

Instead such a rule's contents should be (manually) in-lined in its call sites.


2. **Avoid *_SEP DSL methods (MANY_SEP / AT_LEAST_ONE_SEP).**

The *_SEP DSL methods also collect the separator Tokens parsed. Creating these arrays has a small overhead (several percentage).
Which is a complete waste in most cases where those separators tokens are not needed for any output data structure.

3. **Use the returned values of iteration DSL methods (MANY/MANY_SEP/AT_LEAST_ONE/AT_LEAST_ONE_SEP).**

Consider the following grammar rule:

```javascript
this.RULE("array", function() {
let myArr = []
$.CONSUME(LSquare);
values.push($.SUBRULE($.value));
$.MANY(() => {
$.CONSUME(Comma);
values.push($.SUBRULE2($.value));
});
$.CONSUME(RSquare);
});
```

The values of the array are manually collected inside the "myArr" array.
However another result array is already created by invoking the iteration DSL method "MANY"
This is obviously a waste of cpu cycles...

A slightly more efficient (but syntactically ugly) alternative would be:
```javascript
this.RULE("array", function() {
let myArr = []
$.CONSUME(LSquare);
values.push($.SUBRULE($.value));

let iterationResult =
$.MANY(() => {
$.CONSUME(Comma);
return $.SUBRULE2($.value);
});

myArr = myArr.concat(iterationResult)
$.CONSUME(RSquare);
});
```
4 changes: 2 additions & 2 deletions examples/language_services/src/examples/json/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ export class JsonParser extends Parser {
lCurlyTok = this.CONSUME(LCurly)
commas = this.MANY_SEP(Comma, () => {
objectItemPTs.push(this.SUBRULE2(this.objectItem))
})
}).separators
rCurlyTok = this.CONSUME(RCurly)

return PT(ObjectPT, CHILDREN(objectItemPTs,
Expand All @@ -68,7 +68,7 @@ export class JsonParser extends Parser {
lSquareTok = this.CONSUME(LSquare)
commas = this.MANY_SEP(Comma, () => {
valuePTs.push(this.SUBRULE(this.value))
})
}).separators
rSquareTok = this.CONSUME(RSquare)

return PT(ArrayPT, CHILDREN(valuePTs,
Expand Down
Loading

0 comments on commit 847f5ad

Please sign in to comment.