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

qe: Capabilities-based size optimizations for WASM engine #4701

Merged
merged 12 commits into from
Mar 11, 2024

Conversation

SevInf
Copy link
Contributor

@SevInf SevInf commented Feb 8, 2024

Core feature of this PR: can_have_capability function in psl-core
crate. For multi-connector builds it always returns true and has no
effect. If we are inside of a single connector build, however, it will
eveluate value based on the actual connector capabilities. In many
cases, this will allow optimizer to completely eliminate following code
if connector does not support specific feature.

Notable exeception to that were relation joins: for some reason,
optimizer can not eliminate those functions from SQLite bundle. So, this
is the only place in sql-query-connector where we have to introduce
conditionally compiled feature.

In order to take maximum advantage of this functionality, we have to
disable default features in quaint and psl crates and enable them
only in native engines.

Close https://github.com/prisma/team-orm/issues/928

@SevInf SevInf added this to the 5.10.0 milestone Feb 8, 2024
Copy link
Contributor

github-actions bot commented Feb 8, 2024

WASM Size

Engine This PR Base branch Diff
Postgres 2.059MiB 2.073MiB -13.769KiB
Postgres (gzip) 812.613KiB 817.715KiB -5.103KiB
Mysql 2.026MiB 2.055MiB -29.601KiB
Mysql (gzip) 798.755KiB 809.762KiB -11.007KiB
Sqlite 1.929MiB 2.016MiB -88.998KiB
Sqlite (gzip) 762.282KiB 796.696KiB -34.415KiB

Copy link

codspeed-hq bot commented Feb 8, 2024

CodSpeed Performance Report

Merging #4701 will not alter performance

Comparing feat/more-post-split-reductions (8e43152) with main (0b70883)

Summary

✅ 11 untouched benchmarks

@SevInf SevInf force-pushed the feat/more-post-split-reductions branch 3 times, most recently from c54730b to a06391c Compare February 14, 2024 11:34
Copy link
Contributor

github-actions bot commented Feb 14, 2024

✅ WASM query-engine performance won't change substantially (1.014x)

Full benchmark report
DATABASE_URL="postgresql://postgres:postgres@localhost:5432/bench?schema=imdb_bench&sslmode=disable" \
node --experimental-wasm-modules query-engine/driver-adapters/executor/dist/bench.mjs
"
"
"
"
"
"
"
"
"
"
"
"
"
"
"
"
"
"
"
"
"
"
"
"
"
"
"
"
"
"
"
"
"
"
"
"
cpu: AMD EPYC 7763 64-Core Processor
runtime: node v18.19.1 (x64-linux)

benchmark                   time (avg)             (min … max)       p75       p99      p999
-------------------------------------------------------------- -----------------------------
• movies.findMany() (all - ~50K)
-------------------------------------------------------------- -----------------------------
Web Assembly: Baseline     285 ms/iter       (284 ms … 289 ms)    285 ms    289 ms    289 ms
Web Assembly: Latest       376 ms/iter       (372 ms … 381 ms)    379 ms    381 ms    381 ms
Web Assembly: Current      380 ms/iter       (377 ms … 388 ms)    380 ms    388 ms    388 ms
Node API: Current          198 ms/iter       (196 ms … 211 ms)    199 ms    211 ms    211 ms

summary for movies.findMany() (all - ~50K)
  Web Assembly: Current
   1.91x slower than Node API: Current
   1.33x slower than Web Assembly: Baseline
   1.01x slower than Web Assembly: Latest

• movies.findMany({ take: 2000 })
-------------------------------------------------------------- -----------------------------
Web Assembly: Baseline  11'525 µs/iter (11'242 µs … 14'200 µs) 11'384 µs 14'200 µs 14'200 µs
Web Assembly: Latest    15'303 µs/iter (14'749 µs … 16'720 µs) 15'222 µs 16'720 µs 16'720 µs
Web Assembly: Current   15'428 µs/iter (15'269 µs … 16'504 µs) 15'424 µs 16'504 µs 16'504 µs
Node API: Current        8'081 µs/iter   (7'861 µs … 8'528 µs)  8'139 µs  8'528 µs  8'528 µs

summary for movies.findMany({ take: 2000 })
  Web Assembly: Current
   1.91x slower than Node API: Current
   1.34x slower than Web Assembly: Baseline
   1.01x slower than Web Assembly: Latest

• movies.findMany({ where: {...}, take: 2000 })
-------------------------------------------------------------- -----------------------------
Web Assembly: Baseline   1'856 µs/iter   (1'756 µs … 2'955 µs)  1'837 µs  2'664 µs  2'955 µs
Web Assembly: Latest     2'427 µs/iter   (2'322 µs … 3'839 µs)  2'411 µs  3'690 µs  3'839 µs
Web Assembly: Current    2'501 µs/iter   (2'409 µs … 3'371 µs)  2'494 µs  3'180 µs  3'371 µs
Node API: Current        1'410 µs/iter   (1'317 µs … 1'844 µs)  1'420 µs  1'647 µs  1'844 µs

summary for movies.findMany({ where: {...}, take: 2000 })
  Web Assembly: Current
   1.77x slower than Node API: Current
   1.35x slower than Web Assembly: Baseline
   1.03x slower than Web Assembly: Latest

• movies.findMany({ include: { cast: true } take: 2000 }) (m2m)
-------------------------------------------------------------- -----------------------------
Web Assembly: Baseline     543 ms/iter       (535 ms … 564 ms)    548 ms    564 ms    564 ms
Web Assembly: Latest       726 ms/iter       (719 ms … 741 ms)    732 ms    741 ms    741 ms
Web Assembly: Current      730 ms/iter       (722 ms … 738 ms)    736 ms    738 ms    738 ms
Node API: Current          448 ms/iter       (434 ms … 460 ms)    456 ms    460 ms    460 ms

summary for movies.findMany({ include: { cast: true } take: 2000 }) (m2m)
  Web Assembly: Current
   1.63x slower than Node API: Current
   1.35x slower than Web Assembly: Baseline
   1.01x slower than Web Assembly: Latest

• movies.findMany({ where: {...}, include: { cast: true } take: 2000 }) (m2m)
-------------------------------------------------------------- -----------------------------
Web Assembly: Baseline  74'680 µs/iter (74'501 µs … 74'905 µs) 74'795 µs 74'905 µs 74'905 µs
Web Assembly: Latest       102 ms/iter       (102 ms … 102 ms)    102 ms    102 ms    102 ms
Web Assembly: Current      102 ms/iter       (102 ms … 102 ms)    102 ms    102 ms    102 ms
Node API: Current       59'134 µs/iter (58'699 µs … 59'811 µs) 59'294 µs 59'811 µs 59'811 µs

summary for movies.findMany({ where: {...}, include: { cast: true } take: 2000 }) (m2m)
  Web Assembly: Current
   1.73x slower than Node API: Current
   1.37x slower than Web Assembly: Baseline
   1x faster than Web Assembly: Latest

• movies.findMany({ take: 2000, include: { cast: { include: { person: true } } } })
-------------------------------------------------------------- -----------------------------
Web Assembly: Baseline     973 ms/iter       (964 ms … 989 ms)    985 ms    989 ms    989 ms
Web Assembly: Latest     1'210 ms/iter   (1'198 ms … 1'223 ms)  1'223 ms  1'223 ms  1'223 ms
Web Assembly: Current    1'217 ms/iter   (1'207 ms … 1'238 ms)  1'223 ms  1'238 ms  1'238 ms
Node API: Current          884 ms/iter       (862 ms … 906 ms)    905 ms    906 ms    906 ms

summary for movies.findMany({ take: 2000, include: { cast: { include: { person: true } } } })
  Web Assembly: Current
   1.38x slower than Node API: Current
   1.25x slower than Web Assembly: Baseline
   1.01x slower than Web Assembly: Latest

• movie.findMany({ where: { ... }, take: 2000, include: { cast: { include: { person: true } } } })
-------------------------------------------------------------- -----------------------------
Web Assembly: Baseline     135 ms/iter       (135 ms … 135 ms)    135 ms    135 ms    135 ms
Web Assembly: Latest       169 ms/iter       (167 ms … 171 ms)    171 ms    171 ms    171 ms
Web Assembly: Current      169 ms/iter       (168 ms … 170 ms)    170 ms    170 ms    170 ms
Node API: Current          102 ms/iter       (101 ms … 103 ms)    103 ms    103 ms    103 ms

summary for movie.findMany({ where: { ... }, take: 2000, include: { cast: { include: { person: true } } } })
  Web Assembly: Current
   1.66x slower than Node API: Current
   1.25x slower than Web Assembly: Baseline
   1x faster than Web Assembly: Latest

• movie.findMany({ where: { reviews: { author: { ... } }, take: 100 }) (to-many -> to-one)
-------------------------------------------------------------- -----------------------------
Web Assembly: Baseline     873 µs/iter     (817 µs … 1'363 µs)    868 µs  1'318 µs  1'363 µs
Web Assembly: Latest     1'198 µs/iter   (1'133 µs … 1'730 µs)  1'206 µs  1'572 µs  1'730 µs
Web Assembly: Current    1'245 µs/iter   (1'169 µs … 2'065 µs)  1'238 µs  1'813 µs  2'065 µs
Node API: Current          795 µs/iter     (709 µs … 1'249 µs)    805 µs  1'124 µs  1'249 µs

summary for movie.findMany({ where: { reviews: { author: { ... } }, take: 100 }) (to-many -> to-one)
  Web Assembly: Current
   1.57x slower than Node API: Current
   1.43x slower than Web Assembly: Baseline
   1.04x slower than Web Assembly: Latest

• movie.findMany({ where: { cast: { person: { ... } }, take: 100 }) (m2m -> to-one)
-------------------------------------------------------------- -----------------------------
Web Assembly: Baseline     852 µs/iter     (818 µs … 1'368 µs)    855 µs  1'189 µs  1'368 µs
Web Assembly: Latest     1'223 µs/iter   (1'161 µs … 1'793 µs)  1'225 µs  1'569 µs  1'793 µs
Web Assembly: Current    1'245 µs/iter   (1'198 µs … 1'830 µs)  1'249 µs  1'559 µs  1'830 µs
Node API: Current          784 µs/iter     (713 µs … 1'084 µs)    805 µs    950 µs  1'084 µs

summary for movie.findMany({ where: { cast: { person: { ... } }, take: 100 }) (m2m -> to-one)
  Web Assembly: Current
   1.59x slower than Node API: Current
   1.46x slower than Web Assembly: Baseline
   1.02x slower than Web Assembly: Latest

After changes in 8e43152

@SevInf SevInf force-pushed the feat/more-post-split-reductions branch from 5e6612b to 1eb96ff Compare February 14, 2024 17:13
@SevInf SevInf modified the milestone: 5.10.0 Feb 16, 2024
@SevInf SevInf force-pushed the feat/more-post-split-reductions branch from 5394ce7 to bd67847 Compare February 19, 2024 09:43
@SevInf SevInf force-pushed the feat/more-post-split-reductions branch 3 times, most recently from 6e2e597 to f241016 Compare February 29, 2024 16:27
@@ -37,19 +37,14 @@ pub enum Compare<'a> {
/// without visitor transformation in between.
Raw(Box<Expression<'a>>, Cow<'a, str>, Box<Expression<'a>>),
/// All json related comparators
#[cfg(any(feature = "postgresql", feature = "mysql"))]
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@SevInf SevInf changed the title qe: More per-connector code remval after split qe: Capabilities-based size optimizations for WASM engine Feb 29, 2024
@SevInf SevInf marked this pull request as ready for review February 29, 2024 17:14
@SevInf SevInf requested a review from a team as a code owner February 29, 2024 17:14
@SevInf SevInf requested review from Druue, miguelff and jkomyno and removed request for a team February 29, 2024 17:14
@janpio
Copy link
Contributor

janpio commented Mar 1, 2024

Does the Codspeed performance report here make sense @SevInf?

quaint/src/ast/delete.rs Outdated Show resolved Hide resolved
quaint/src/ast/insert.rs Outdated Show resolved Hide resolved
@SevInf SevInf force-pushed the feat/more-post-split-reductions branch from e467f64 to d84aa2a Compare March 5, 2024 11:40
@jkomyno
Copy link
Contributor

jkomyno commented Mar 5, 2024

✅ to the most recent set of changes. Good job, @SevInf!

@SevInf
Copy link
Contributor Author

SevInf commented Mar 5, 2024

Does the Codspeed performance report here make sense @SevInf?

It was not, fixed it.

Sergey Tatarintsev added 12 commits March 7, 2024 18:05
Core feature of this PR: `can_have_capability` function in `psl-core`
crate. For multi-connector builds it always returns `true` and has no
effect. If we are inside of a single connector build, however, it will
eveluate value based on the actual connector capabilities. In many
cases, this will allow optimizer to completely eliminate following code
if connector does not support specific feature.

Notable exeception to that were relation joins: for some reason,
optimizer can not eliminate those functions from SQLite bundle. So, this
is the only place in sql-query-connector where we have to introduce
conditionally compiled feature.

In order to take maximum advantage of this functionality, we have to
disable default features in `quaint` and `psl` crates and enable them
only in native engines.

Close prisma/team-orm#928
@SevInf SevInf force-pushed the feat/more-post-split-reductions branch from 09f5b0d to 8e43152 Compare March 7, 2024 17:05
@SevInf SevInf merged commit 715c8eb into main Mar 11, 2024
140 checks passed
@SevInf SevInf deleted the feat/more-post-split-reductions branch March 11, 2024 11:32
SevInf pushed a commit that referenced this pull request Mar 11, 2024
SevInf pushed a commit that referenced this pull request Mar 11, 2024
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.

3 participants