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

Performance improvements for the event query API #7319

Merged
merged 21 commits into from
Nov 29, 2021
Merged

Conversation

creachadair
Copy link
Contributor

@creachadair creachadair commented Nov 25, 2021

Rework the implementation of event query parsing and execution to improve performance and reduce memory usage.

Previous memory and CPU profiles of the pubsub service showed query processing as a significant hotspot. While we don't have evidence that this is visibly hurting users, fixing it is fairly easy and self-contained.

Updates #6439.

Structure

  • Move the existing query implementation to the oldquery subdirectory. This can probably be deleted before merging.
  • Add a syntax subpackage providing a lexical scanner and parser to replace the generated PEG parser.
  • Pre-compile the query to avoid repeated syntax traversal and allocations during matching.
  • Update usage in the rest of the repository.

Benchmarks

Typical benchmark results comparing the original implementation (PEG) with the reworked implementation (Custom):

TEST                        TIME/OP  BYTES/OP  ALLOCS/OP  SPEEDUP   MEM SAVING
BenchmarkParsePEG-12       51716 ns  526832    27
BenchmarkParseCustom-12     2167 ns    4616    17         23.8x     99.1%
BenchmarkMatchPEG-12        3086 ns    1097    22
BenchmarkMatchCustom-12    294.2 ns      64     3         10.5x     94.1%

@tac0turtle
Copy link
Contributor

closes #6439.

Amazing work!!

@creachadair
Copy link
Contributor Author

closes #6439.

Amazing work!!

I'm not sure it entirely fixes #6439, quite a lot of memory per subscription is also spent on queuing and buffering messages for the clients. This should help some, though. 🙂

@creachadair creachadair force-pushed the mjf/weary-query branch 2 times, most recently from 96eb55d to 1d9e519 Compare November 28, 2021 01:50
Copy link
Contributor

@cmwaters cmwaters left a comment

Choose a reason for hiding this comment

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

LGTM although I haven't really done a deep dive. I just have a few questions?

This doesn't change any query parsing behavior right?

libs/pubsub/query/query.go Show resolved Hide resolved
libs/pubsub/query/query.go Show resolved Hide resolved
libs/pubsub/query/bench_test.go Show resolved Hide resolved
libs/pubsub/query/oldquery/query_test.go Show resolved Hide resolved
libs/pubsub/query/oldquery/query_test.go Show resolved Hide resolved
libs/pubsub/query/syntax/parser.go Show resolved Hide resolved
types/events_test.go Show resolved Hide resolved
M. J. Fromberger added 18 commits November 29, 2021 08:34
So we can still test and benchmark, but leaves the main package clear for the
new implementation.

Also: emove unused test case fields

All the tests in this group are expected to compile.
Remove the compile-error check field, which was always false.

All the tests in this group do not want a match error.
Remove the match-error check field.
These are the same test cases that the original implementation uses.
Remove the one that doesn't pass for silly reasons, and document why.
Compiled -> Query
update receiver names
fix usage in test
Results:
 BenchmarkParsePEG-12     24410    48992  ns/op  526828  B/op  27  alloc/op
 BenchmarkParseCustom-12  566208   2150   ns/op  4616    B/op  17  alloc/op
 BenchmarkMatchPEG-12     396376   3082   ns/op  1097    B/op  22  alloc/op
 BenchmarkMatchCustom-12  4125183  287.4  ns/op  64      B/op  3   alloc/op
This ensures the examples are likely to be somewhat correct.
This replaces the old "Empty" query, whose name described the implementation
rather than the effect.
Also update generated mocks.

Directories:

  - internal/eventbus
  - internal/inspect
  - internal/state/indexer
  - libs/pubsub
  - types
Some of these are incredibly useless.
@creachadair creachadair merged commit 1dca1a8 into master Nov 29, 2021
@creachadair creachadair deleted the mjf/weary-query branch November 29, 2021 21:08
creachadair pushed a commit that referenced this pull request Nov 29, 2021
creachadair pushed a commit that referenced this pull request Nov 29, 2021
creachadair pushed a commit that referenced this pull request Nov 29, 2021
creachadair pushed a commit that referenced this pull request Nov 29, 2021
creachadair pushed a commit that referenced this pull request Nov 30, 2021
creachadair pushed a commit that referenced this pull request Nov 30, 2021
lklimek referenced this pull request in dashpay/tenderdash Mar 25, 2022
A manual backport of #7319 and #7336.

(cherry picked from commit 1c1ce83)
mmsqe pushed a commit to mmsqe/tendermint that referenced this pull request Aug 30, 2022
Rework the implementation of event query parsing and execution to
improve performance and reduce memory usage.

Previous memory and CPU profiles of the pubsub service showed query
processing as a significant hotspot. While we don't have evidence that
this is visibly hurting users, fixing it is fairly easy and self-contained.

Updates tendermint#6439.

Typical benchmark results comparing the original implementation (PEG) with the reworked implementation (Custom):
```
TEST                        TIME/OP  BYTES/OP  ALLOCS/OP  SPEEDUP   MEM SAVING
BenchmarkParsePEG-12       51716 ns  526832    27
BenchmarkParseCustom-12     2167 ns    4616    17         23.8x     99.1%
BenchmarkMatchPEG-12        3086 ns    1097    22
BenchmarkMatchCustom-12    294.2 ns      64     3         10.5x     94.1%
```

Components:
* Add a basic parsing benchmark.
* Move the original query implementation to a subdirectory.
* Add lexical scanner for Query expressions.
* Add a parser for Query expressions.
* Implement query compiler.
* Add test cases based on OpenAPI examples.
* Add MustCompile to replace the original MustParse, and update usage.
mmsqe pushed a commit to mmsqe/tendermint that referenced this pull request Aug 30, 2022
Rework the implementation of event query parsing and execution to
improve performance and reduce memory usage.

Previous memory and CPU profiles of the pubsub service showed query
processing as a significant hotspot. While we don't have evidence that
this is visibly hurting users, fixing it is fairly easy and self-contained.

Updates tendermint#6439.

Typical benchmark results comparing the original implementation (PEG) with the reworked implementation (Custom):
```
TEST                        TIME/OP  BYTES/OP  ALLOCS/OP  SPEEDUP   MEM SAVING
BenchmarkParsePEG-12       51716 ns  526832    27
BenchmarkParseCustom-12     2167 ns    4616    17         23.8x     99.1%
BenchmarkMatchPEG-12        3086 ns    1097    22
BenchmarkMatchCustom-12    294.2 ns      64     3         10.5x     94.1%
```

Components:
* Add a basic parsing benchmark.
* Move the original query implementation to a subdirectory.
* Add lexical scanner for Query expressions.
* Add a parser for Query expressions.
* Implement query compiler.
* Add test cases based on OpenAPI examples.
* Add MustCompile to replace the original MustParse, and update usage.
mmsqe pushed a commit to mmsqe/tendermint that referenced this pull request Aug 30, 2022
Rework the implementation of event query parsing and execution to
improve performance and reduce memory usage.

Previous memory and CPU profiles of the pubsub service showed query
processing as a significant hotspot. While we don't have evidence that
this is visibly hurting users, fixing it is fairly easy and self-contained.

Updates tendermint#6439.

Typical benchmark results comparing the original implementation (PEG) with the reworked implementation (Custom):
```
TEST                        TIME/OP  BYTES/OP  ALLOCS/OP  SPEEDUP   MEM SAVING
BenchmarkParsePEG-12       51716 ns  526832    27
BenchmarkParseCustom-12     2167 ns    4616    17         23.8x     99.1%
BenchmarkMatchPEG-12        3086 ns    1097    22
BenchmarkMatchCustom-12    294.2 ns      64     3         10.5x     94.1%
```

Components:
* Add a basic parsing benchmark.
* Move the original query implementation to a subdirectory.
* Add lexical scanner for Query expressions.
* Add a parser for Query expressions.
* Implement query compiler.
* Add test cases based on OpenAPI examples.
* Add MustCompile to replace the original MustParse, and update usage.
mmsqe pushed a commit to mmsqe/tendermint that referenced this pull request Aug 30, 2022
Rework the implementation of event query parsing and execution to
improve performance and reduce memory usage.

Previous memory and CPU profiles of the pubsub service showed query
processing as a significant hotspot. While we don't have evidence that
this is visibly hurting users, fixing it is fairly easy and self-contained.

Updates tendermint#6439.

Typical benchmark results comparing the original implementation (PEG) with the reworked implementation (Custom):
```
TEST                        TIME/OP  BYTES/OP  ALLOCS/OP  SPEEDUP   MEM SAVING
BenchmarkParsePEG-12       51716 ns  526832    27
BenchmarkParseCustom-12     2167 ns    4616    17         23.8x     99.1%
BenchmarkMatchPEG-12        3086 ns    1097    22
BenchmarkMatchCustom-12    294.2 ns      64     3         10.5x     94.1%
```

Components:
* Add a basic parsing benchmark.
* Move the original query implementation to a subdirectory.
* Add lexical scanner for Query expressions.
* Add a parser for Query expressions.
* Implement query compiler.
* Add test cases based on OpenAPI examples.
* Add MustCompile to replace the original MustParse, and update usage.
cmwaters pushed a commit that referenced this pull request Sep 13, 2022
…9334)

* Performance improvements for the event query API (#7319)

Rework the implementation of event query parsing and execution to
improve performance and reduce memory usage.

Previous memory and CPU profiles of the pubsub service showed query
processing as a significant hotspot. While we don't have evidence that
this is visibly hurting users, fixing it is fairly easy and self-contained.

Updates #6439.

Typical benchmark results comparing the original implementation (PEG) with the reworked implementation (Custom):
```
TEST                        TIME/OP  BYTES/OP  ALLOCS/OP  SPEEDUP   MEM SAVING
BenchmarkParsePEG-12       51716 ns  526832    27
BenchmarkParseCustom-12     2167 ns    4616    17         23.8x     99.1%
BenchmarkMatchPEG-12        3086 ns    1097    22
BenchmarkMatchCustom-12    294.2 ns      64     3         10.5x     94.1%
```
mmsqe pushed a commit to mmsqe/tendermint that referenced this pull request Sep 22, 2022
mmsqe added a commit to mmsqe/tendermint that referenced this pull request Dec 9, 2022
…t#7319) (tendermint#9334)

* Performance improvements for the event query API (tendermint#7319)

Rework the implementation of event query parsing and execution to
improve performance and reduce memory usage.

Previous memory and CPU profiles of the pubsub service showed query
processing as a significant hotspot. While we don't have evidence that
this is visibly hurting users, fixing it is fairly easy and self-contained.

Updates tendermint#6439.

Typical benchmark results comparing the original implementation (PEG) with the reworked implementation (Custom):
```
TEST                        TIME/OP  BYTES/OP  ALLOCS/OP  SPEEDUP   MEM SAVING
BenchmarkParsePEG-12       51716 ns  526832    27
BenchmarkParseCustom-12     2167 ns    4616    17         23.8x     99.1%
BenchmarkMatchPEG-12        3086 ns    1097    22
BenchmarkMatchCustom-12    294.2 ns      64     3         10.5x     94.1%
```
mmsqe added a commit to mmsqe/tendermint that referenced this pull request Dec 9, 2022
…t#7319) (tendermint#9334)

* Performance improvements for the event query API (tendermint#7319)

Rework the implementation of event query parsing and execution to
improve performance and reduce memory usage.

Previous memory and CPU profiles of the pubsub service showed query
processing as a significant hotspot. While we don't have evidence that
this is visibly hurting users, fixing it is fairly easy and self-contained.

Updates tendermint#6439.

Typical benchmark results comparing the original implementation (PEG) with the reworked implementation (Custom):
```
TEST                        TIME/OP  BYTES/OP  ALLOCS/OP  SPEEDUP   MEM SAVING
BenchmarkParsePEG-12       51716 ns  526832    27
BenchmarkParseCustom-12     2167 ns    4616    17         23.8x     99.1%
BenchmarkMatchPEG-12        3086 ns    1097    22
BenchmarkMatchCustom-12    294.2 ns      64     3         10.5x     94.1%
```
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.

None yet

4 participants