Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve parser creation formance. #57

Merged
merged 2 commits into from
Jul 20, 2024
Merged

Conversation

pereman2
Copy link
Contributor

@pereman2 pereman2 commented Jul 16, 2024

Hello and sorry for the intrusion but... I was running some benchmark for https://github.com/penberg/limbo and I found out Parser::new was doing a whole bunch of memmove due to the stack approach used by SmallVec. This PR removes SmallVec in favor of Vec as you will see proven as worth it, by the benchmarks you guys have inside benches/sqlparser_bench.rs:

This move creates a huge different in Parser::new, and when I say huge, I say a whopping 1444% difference. SmallVec triggers too many memmoves.

# With Vec::new()  ------------------------------------------------
     Running benches/sqlparser_bench.rs (target/release/deps/sqlparser_bench-90367034c12b9cef)
sqlparser-rs parsing benchmark/sqlparser::select
                        time:   [257.62 ns 258.12 ns 258.69 ns]
# With SmallVec::new()  ------------------------------------------------

sqlparser-rs parsing benchmark/sqlparser::select
                        time:   [3.9573 µs 3.9604 µs 3.9654 µs]
                        change: [+1443.7% +1449.0% +1453.8%] (p = 0.00 < 0.05)
                        Performance has regressed.

This move creates a huge different in Parser::new, and when I say, huge
I say 1444%. SmallVec triggers too many memmoves.

```bash
     Running benches/sqlparser_bench.rs (target/release/deps/sqlparser_bench-90367034c12b9cef)
sqlparser-rs parsing benchmark/sqlparser::select
                        time:   [257.62 ns 258.12 ns 258.69 ns]

sqlparser-rs parsing benchmark/sqlparser::select
                        time:   [3.9573 µs 3.9604 µs 3.9654 µs]
                        change: [+1443.7% +1449.0% +1453.8%] (p = 0.00 < 0.05)
                        Performance has regressed.
```

Signed-off-by: Pere Diaz Bou <[email protected]>
Signed-off-by: Pere Diaz Bou <[email protected]>
@pereman2
Copy link
Contributor Author

@gwenn ping :)

@gwenn
Copy link
Owner

gwenn commented Jul 16, 2024

@pereman2 pong :)

@gwenn
Copy link
Owner

gwenn commented Jul 17, 2024

I can reproduce your results:

sqlparser_bench % cargo bench # master
sqlparser-rs parsing benchmark/sqlparser::select
                        time:   [15.510 µs 16.289 µs 17.324 µs]
Found 11 outliers among 100 measurements (11.00%)
  8 (8.00%) high mild
  3 (3.00%) high severe
sqlparser-rs parsing benchmark/sqlparser::with_select
                        time:   [31.396 µs 32.301 µs 33.468 µs]
Found 8 outliers among 100 measurements (8.00%)
  5 (5.00%) high mild
  3 (3.00%) high severe
sqlparser_bench % cargo bench # your branch
sqlparser-rs parsing benchmark/sqlparser::select
                        time:   [433.49 ns 435.21 ns 437.12 ns]
                        change: [-97.356% -97.272% -97.198%] (p = 0.00 < 0.05)
                        Performance has improved.
Found 11 outliers among 100 measurements (11.00%)
  3 (3.00%) high mild
  8 (8.00%) high severe
sqlparser-rs parsing benchmark/sqlparser::with_select
                        time:   [445.34 ns 447.70 ns 450.63 ns]
                        change: [-98.615% -98.579% -98.548%] (p = 0.00 < 0.05)
                        Performance has improved.
Found 10 outliers among 100 measurements (10.00%)
  3 (3.00%) high mild
  7 (7.00%) high severe

@pereman2
Copy link
Contributor Author

Nice

@gwenn gwenn mentioned this pull request Jul 20, 2024
@gwenn
Copy link
Owner

gwenn commented Jul 20, 2024

In fact, you were benchmarking Parser::new + StackOverflow...
See f83a162

Benchmarking sqlparser-rs parsing benchmark/sqlparser::select: Warming up for 3.0000 sthread 'main' panicked at benches/sqlparser_bench.rs:24:35:
called `Result::unwrap()` on an `Err` value: ParserError(StackOverflow, Some((1, 7)))
stack backtrace:
   0: _rust_begin_unwind
   1: core::panicking::panic_fmt
   2: core::result::unwrap_failed
   3: criterion::bencher::Bencher<M>::iter
   4: <criterion::routine::Function<M,F,T> as criterion::routine::Routine<M,T>>::warm_up
   5: criterion::routine::Routine::sample
   6: criterion::analysis::common
   7: criterion::benchmark_group::BenchmarkGroup<M>::bench_with_input
   8: sqlparser_bench::main

@gwenn gwenn merged commit fb5e01b into gwenn:master Jul 20, 2024
0 of 2 checks passed
@gwenn gwenn mentioned this pull request Jul 20, 2024
@pereman2
Copy link
Contributor Author

In fact, you were benchmarking Parser::new + StackOverflow... See f83a162

Benchmarking sqlparser-rs parsing benchmark/sqlparser::select: Warming up for 3.0000 sthread 'main' panicked at benches/sqlparser_bench.rs:24:35:
called `Result::unwrap()` on an `Err` value: ParserError(StackOverflow, Some((1, 7)))
stack backtrace:
   0: _rust_begin_unwind
   1: core::panicking::panic_fmt
   2: core::result::unwrap_failed
   3: criterion::bencher::Bencher<M>::iter
   4: <criterion::routine::Function<M,F,T> as criterion::routine::Routine<M,T>>::warm_up
   5: criterion::routine::Routine::sample
   6: criterion::analysis::common
   7: criterion::benchmark_group::BenchmarkGroup<M>::bench_with_input
   8: sqlparser_bench::main

oh wow didn't notice

@gwenn
Copy link
Owner

gwenn commented Jul 20, 2024

But you made sqlite3-parser on par with sqlparser-rs:
https://github.com/gwenn/lemon-rs/blob/master/sqlparser_bench/README.md
Thanks.

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