Skip to content

[Pratt parser] Add EnablePrattParser option and dual-mode testing - #1433

Open
dmitriplotnikov wants to merge 2 commits into
masterfrom
pratt-parser-option
Open

[Pratt parser] Add EnablePrattParser option and dual-mode testing#1433
dmitriplotnikov wants to merge 2 commits into
masterfrom
pratt-parser-option

Conversation

@dmitriplotnikov

Copy link
Copy Markdown
Collaborator

Overview

  • Extracted ANTLR parser implementation into parser/antlr_parser.go
  • Added EnablePrattParser option in parser/options.go
  • Added parser dispatcher in parser/parser.go to route between ANTLR and Pratt parsers
  • Updated parser_test.go to run all test cases and benchmarks across both parsers
  • Cleaned up redundant duplicate test cases from pratt_parser_test.go

Benchmark Results

Single-threaded (BenchmarkByCategory)

Benchmark Category Implementation Time (ns/op) Memory (B/op) Allocs/op Speedup / Memory Reduction
Simple ANTLR
Pratt
325,234 ns/op
30,759 ns/op
110,000 B/op
13,549 B/op
1,646 allocs/op
404 allocs/op
~10.6x faster
~8.1x less memory (4.1x fewer allocs)
Complex ANTLR
Pratt
1,179,666 ns/op
124,332 ns/op
415,741 B/op
51,864 B/op
5,401 allocs/op
1,397 allocs/op
~9.5x faster
~8.0x less memory (3.9x fewer allocs)
Macros ANTLR
Pratt
422,952 ns/op
57,192 ns/op
138,618 B/op
23,930 B/op
2,049 allocs/op
641 allocs/op
~7.4x faster
~5.8x less memory (3.2x fewer allocs)
Errors ANTLR
Pratt
1,646,118 ns/op
99,719 ns/op
598,315 B/op
37,808 B/op
7,945 allocs/op
1,176 allocs/op
~16.5x faster
~15.8x less memory (6.8x fewer allocs)

Parallel Execution (BenchmarkParallelByCategory)

Benchmark Category Implementation Time (ns/op) Memory (B/op) Allocs/op Speedup / Memory Reduction
Simple ANTLR
Pratt
199,177 ns/op
6,922 ns/op
110,128 B/op
13,494 B/op
1,649 allocs/op
404 allocs/op
~28.8x faster
~8.2x less memory
Complex ANTLR
Pratt
660,746 ns/op
27,752 ns/op
414,872 B/op
51,865 B/op
5,406 allocs/op
1,397 allocs/op
~23.8x faster
~8.0x less memory
Macros ANTLR
Pratt
219,749 ns/op
12,887 ns/op
138,100 B/op
23,732 B/op
2,053 allocs/op
641 allocs/op
~17.0x faster
~5.8x less memory
Errors ANTLR
Pratt
827,582 ns/op
21,358 ns/op
597,451 B/op
37,645 B/op
7,955 allocs/op
1,176 allocs/op
~38.7x faster
~15.9x less memory

- Added `EnablePrattParser` option in `parser/options.go`
- Added dispatcher in `parser/parser.go` to route between ANTLR and Pratt parsers
- Updated `parser_test.go` to run all tests and benchmarks across both parsers
- Cleaned up duplicate test cases from `pratt_parser_test.go`

### Single-threaded (`BenchmarkByCategory`)
| Benchmark Category | Implementation | Time (ns/op) | Memory (B/op) | Allocs/op | Speedup / Memory Reduction |
| :--- | :--- | :--- | :--- | :--- | :--- |
| **Simple** | **ANTLR**<br>**Pratt** | 325,234 ns/op<br>**30,759 ns/op** | 110,000 B/op<br>**13,549 B/op** | 1,646 allocs/op<br>**404 allocs/op** | **~10.6x faster**<br>**~8.1x less memory (4.1x fewer allocs)** |
| **Complex** | **ANTLR**<br>**Pratt** | 1,179,666 ns/op<br>**124,332 ns/op** | 415,741 B/op<br>**51,864 B/op** | 5,401 allocs/op<br>**1,397 allocs/op** | **~9.5x faster**<br>**~8.0x less memory (3.9x fewer allocs)** |
| **Macros** | **ANTLR**<br>**Pratt** | 422,952 ns/op<br>**57,192 ns/op** | 138,618 B/op<br>**23,930 B/op** | 2,049 allocs/op<br>**641 allocs/op** | **~7.4x faster**<br>**~5.8x less memory (3.2x fewer allocs)** |
| **Errors** | **ANTLR**<br>**Pratt** | 1,646,118 ns/op<br>**99,719 ns/op** | 598,315 B/op<br>**37,808 B/op** | 7,945 allocs/op<br>**1,176 allocs/op** | **~16.5x faster**<br>**~15.8x less memory (6.8x fewer allocs)** |

### Parallel Execution (`BenchmarkParallelByCategory`)
| Benchmark Category | Implementation | Time (ns/op) | Memory (B/op) | Allocs/op | Speedup / Memory Reduction |
| :--- | :--- | :--- | :--- | :--- | :--- |
| **Simple** | **ANTLR**<br>**Pratt** | 199,177 ns/op<br>**6,922 ns/op** | 110,128 B/op<br>**13,494 B/op** | 1,649 allocs/op<br>**404 allocs/op** | **~28.8x faster**<br>**~8.2x less memory** |
| **Complex** | **ANTLR**<br>**Pratt** | 660,746 ns/op<br>**27,752 ns/op** | 414,872 B/op<br>**51,865 B/op** | 5,406 allocs/op<br>**1,397 allocs/op** | **~23.8x faster**<br>**~8.0x less memory** |
| **Macros** | **ANTLR**<br>**Pratt** | 219,749 ns/op<br>**12,887 ns/op** | 138,100 B/op<br>**23,732 B/op** | 2,053 allocs/op<br>**641 allocs/op** | **~17.0x faster**<br>**~5.8x less memory** |
| **Errors** | **ANTLR**<br>**Pratt** | 827,582 ns/op<br>**21,358 ns/op** | 597,451 B/op<br>**37,645 B/op** | 7,955 allocs/op<br>**1,176 allocs/op** | **~38.7x faster**<br>**~15.9x less memory** |
Comment thread parser/parser.go
} else {
out = impl.parse(buf, source.Description())
if p.enablePrattParser {
return (&PrattParser{options: p.options}).Parse(source)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the PrattParser and AntlrParser are internal details, we can keep the symbols unexported (lower-cased) and that will make it easier to control dependencies.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants