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

fix: make expression log syntax easier to understand #4819

Merged
merged 3 commits into from
Apr 11, 2024

Conversation

laplab
Copy link
Contributor

@laplab laplab commented Apr 9, 2024

main branch
              GET FIRST NON EMPTY ["5"]
                GET FIRST NON EMPTY ["10", "8"]
                      GET FIRST NON EMPTY ["7"]
                              GET FIRST NON EMPTY ["4"]
                                READ RecordQuery(name: 'upsertOneNode', selection: FieldSelection { fields: [Node.id] }, filter: Some(And([Scalar(ScalarFilter { projection: SingleProjection("Node.id"), condition: Equals(Value(Int(1))), mode: Default })])))
                              bind 4
                            LET
                              WRITE UpdateRecord(model: Node, filter: RecordFilter { filter: And([And([Scalar(ScalarFilter { projection: SingleProjection("Node.id"), condition: Equals(Value(Int(1))), mode: Default })]), Empty]), selectors: Some([[("Node.id", Int(1))]]) }, args: WriteArgs { request_now: DateTime(2024-04-09T14:37:52.357+00:00), args: {DatasourceFieldName("value"): Scalar(Set(Int(5)))} }, selected_fields: Some("FieldSelection { fields: [Node.id] }"))
                            bind 2
                          LET
                        SEQ
                      bind 7
                    LET
                      READ RelatedRecordsQuery(name: 'find_children_by_parent', parent model: 'Node', parent relation field: 'leftOf', selection: FieldSelection { fields: [Node.id, Node.leftId] })
                    bind 8
                  LET
                bind 8
                      GET FIRST NON EMPTY ["9"]
                      bind 9
                    LET
                      READ RelatedRecordsQuery(name: 'find_children_by_parent', parent model: 'Node', parent relation field: 'rightOf', selection: FieldSelection { fields: [Node.id, Node.rightId] })
                    bind 10
                  LET
                bind 10
              LET
                RETURN
              bind 6
            LET
          SEQ
        IF
      bind 5
    LET
      READ ManyRecordsQuery(name: 'read_ids_infallible', model: 'Node', selection: FieldSelection { fields: [Node.id] }, args: QueryArguments { model: "Node", cursor: None, take: None, skip: None, filter: Some(And([And([Scalar(ScalarFilter { projection: SingleProjection("Node.id"), condition: Equals(Value(Int(1))), mode: Default })]), Empty])), order_by: [], distinct: None, ignore_skip: false, ignore_take: false, relation_load_strategy: None })
    bind 0
  LET
SEQ
This PR
[
  let
    0 = {
      readExecute ManyRecordsQuery(name: 'read_ids_infallible', model: 'Node', selection: FieldSelection { fields: [Node.id] }, args: QueryArguments { model: "Node", cursor: None, take: None, skip: None, filter: Some(And([And([Scalar(ScalarFilter { projection: SingleProjection("Node.id"), condition: Equals(Value(Int(1))), mode: Default })]), Empty])), order_by: [], distinct: None, ignore_skip: false, ignore_take: false, relation_load_strategy: None })
    },
  in {
    let
      5 = {
        execute <lambda function> {
          if <lambda condition> = true {
            [
              let
                6 = {
                  execute <lambda function> {
                  }
                },
              in {
                let
                  10 = {
                    let
                      10 = {
                        execute <lambda function> {
                          readExecute RelatedRecordsQuery(name: 'find_children_by_parent', parent model: 'Node', parent relation field: 'rightOf', selection: FieldSelection { fields: [Node.id, Node.rightId] })
                        }
                      },
                    in {
                      let
                        9 = {
                          execute <lambda function> {
                            []
                          }
                        },
                      in {
                        getFirstNonEmpty ["9"]
                      }
                    }
                  },
                  8 = {
                    let
                      8 = {
                        execute <lambda function> {
                          readExecute RelatedRecordsQuery(name: 'find_children_by_parent', parent model: 'Node', parent relation field: 'leftOf', selection: FieldSelection { fields: [Node.id, Node.leftId] })
                        }
                      },
                    in {
                      let
                        7 = {
                          execute <lambda function> {
                            [
                              let
                                2 = {
                                  execute <lambda function> {
                                    writeExecute UpdateRecord(model: Node, filter: RecordFilter { filter: And([And([Scalar(ScalarFilter { projection: SingleProjection("Node.id"), condition: Equals(Value(Int(1))), mode: Default })]), Empty]), selectors: Some([[("Node.id", Int(1))]]) }, args: WriteArgs { request_now: DateTime(2024-04-09T14:34:01.261+00:00), args: {DatasourceFieldName("value"): Scalar(Set(Int(5)))} }, selected_fields: Some("FieldSelection { fields: [Node.id] }"))
                                  }
                                },
                              in {
                                let
                                  4 = {
                                    execute <lambda function> {
                                      readExecute RecordQuery(name: 'upsertOneNode', selection: FieldSelection { fields: [Node.id] }, filter: Some(And([Scalar(ScalarFilter { projection: SingleProjection("Node.id"), condition: Equals(Value(Int(1))), mode: Default })])))
                                    }
                                  },
                                in {
                                  getFirstNonEmpty ["4"]
                                }
                              }
                              ,
                            ]
                          }
                        },
                      in {
                        getFirstNonEmpty ["7"]
                      }
                    }
                  },
                in {
                  getFirstNonEmpty ["10", "8"]
                }
              }
              ,
            ]
          }
        }
      },
    in {
      getFirstNonEmpty ["5"]
    }
  }
  ,
]

@laplab laplab requested a review from a team as a code owner April 9, 2024 14:39
@laplab laplab requested review from Druue and removed request for a team April 9, 2024 14:39
Copy link
Contributor

github-actions bot commented Apr 9, 2024

WASM Query Engine file Size

Engine This PR Base branch Diff
Postgres 2.125MiB 2.122MiB 2.867KiB
Postgres (gzip) 835.971KiB 835.681KiB 297.000B
Mysql 2.095MiB 2.092MiB 2.858KiB
Mysql (gzip) 823.820KiB 823.416KiB 414.000B
Sqlite 1.990MiB 1.987MiB 2.870KiB
Sqlite (gzip) 784.572KiB 783.935KiB 652.000B

Copy link

codspeed-hq bot commented Apr 9, 2024

CodSpeed Performance Report

Merging #4819 will improve performances by 5.65%

Comparing fix/expression-formatting (10b8db3) with main (8b36be3)

Summary

⚡ 1 improvements
✅ 10 untouched benchmarks

Benchmarks breakdown

Benchmark main fix/expression-formatting Change
large_read 8.1 ms 7.7 ms +5.65%

Copy link
Contributor

github-actions bot commented Apr 9, 2024

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

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.20.1 (x64-linux)

benchmark                   time (avg)             (min … max)       p75       p99      p999
-------------------------------------------------------------- -----------------------------
• movies.findMany() (all - ~50K)
-------------------------------------------------------------- -----------------------------
Web Assembly: Baseline     369 ms/iter       (365 ms … 373 ms)    372 ms    373 ms    373 ms
Web Assembly: Latest       455 ms/iter       (452 ms … 467 ms)    457 ms    467 ms    467 ms
Web Assembly: Current      451 ms/iter       (447 ms … 460 ms)    456 ms    460 ms    460 ms
Node API: Current          198 ms/iter       (195 ms … 204 ms)    199 ms    204 ms    204 ms

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

• movies.findMany({ take: 2000 })
-------------------------------------------------------------- -----------------------------
Web Assembly: Baseline  14'852 µs/iter (14'615 µs … 17'560 µs) 14'807 µs 17'560 µs 17'560 µs
Web Assembly: Latest    18'223 µs/iter (18'011 µs … 19'667 µs) 18'286 µs 19'667 µs 19'667 µs
Web Assembly: Current   18'185 µs/iter (18'012 µs … 19'002 µs) 18'220 µs 19'002 µs 19'002 µs
Node API: Current        8'225 µs/iter  (7'902 µs … 11'075 µs)  8'058 µs 11'075 µs 11'075 µs

summary for movies.findMany({ take: 2000 })
  Web Assembly: Current
   2.21x slower than Node API: Current
   1.22x slower than Web Assembly: Baseline
   1x faster than Web Assembly: Latest

• movies.findMany({ where: {...}, take: 2000 })
-------------------------------------------------------------- -----------------------------
Web Assembly: Baseline   2'312 µs/iter   (2'195 µs … 3'580 µs)  2'304 µs  3'295 µs  3'580 µs
Web Assembly: Latest     2'879 µs/iter   (2'772 µs … 3'546 µs)  2'871 µs  3'338 µs  3'546 µs
Web Assembly: Current    2'877 µs/iter   (2'751 µs … 4'803 µs)  2'828 µs  3'670 µs  4'803 µs
Node API: Current        1'425 µs/iter   (1'321 µs … 1'900 µs)  1'424 µs  1'795 µs  1'900 µs

summary for movies.findMany({ where: {...}, take: 2000 })
  Web Assembly: Current
   2.02x slower than Node API: Current
   1.24x slower than Web Assembly: Baseline
   1x faster than Web Assembly: Latest

• movies.findMany({ include: { cast: true } take: 2000 }) (m2m)
-------------------------------------------------------------- -----------------------------
Web Assembly: Baseline     570 ms/iter       (563 ms … 592 ms)    569 ms    592 ms    592 ms
Web Assembly: Latest       781 ms/iter       (774 ms … 799 ms)    793 ms    799 ms    799 ms
Web Assembly: Current      789 ms/iter       (781 ms … 809 ms)    801 ms    809 ms    809 ms
Node API: Current          473 ms/iter       (462 ms … 480 ms)    480 ms    480 ms    480 ms

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

• movies.findMany({ where: {...}, include: { cast: true } take: 2000 }) (m2m)
-------------------------------------------------------------- -----------------------------
Web Assembly: Baseline  78'257 µs/iter (77'873 µs … 78'875 µs) 78'768 µs 78'875 µs 78'875 µs
Web Assembly: Latest       110 ms/iter       (110 ms … 111 ms)    111 ms    111 ms    111 ms
Web Assembly: Current      111 ms/iter       (110 ms … 112 ms)    111 ms    112 ms    112 ms
Node API: Current       63'821 µs/iter (62'129 µs … 65'094 µs) 64'657 µs 65'094 µs 65'094 µs

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

• movies.findMany({ take: 2000, include: { cast: { include: { person: true } } } })
-------------------------------------------------------------- -----------------------------
Web Assembly: Baseline   1'004 ms/iter     (995 ms … 1'020 ms)  1'019 ms  1'020 ms  1'020 ms
Web Assembly: Latest     1'299 ms/iter   (1'285 ms … 1'316 ms)  1'315 ms  1'316 ms  1'316 ms
Web Assembly: Current    1'313 ms/iter   (1'301 ms … 1'330 ms)  1'325 ms  1'330 ms  1'330 ms
Node API: Current          887 ms/iter       (857 ms … 916 ms)    915 ms    916 ms    916 ms

summary for movies.findMany({ take: 2000, include: { cast: { include: { person: true } } } })
  Web Assembly: Current
   1.48x slower than Node API: Current
   1.31x 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     145 ms/iter       (143 ms … 151 ms)    144 ms    151 ms    151 ms
Web Assembly: Latest       186 ms/iter       (185 ms … 187 ms)    186 ms    187 ms    187 ms
Web Assembly: Current      188 ms/iter       (186 ms … 191 ms)    191 ms    191 ms    191 ms
Node API: Current          112 ms/iter       (108 ms … 114 ms)    114 ms    114 ms    114 ms

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

• movie.findMany({ where: { reviews: { author: { ... } }, take: 100 }) (to-many -> to-one)
-------------------------------------------------------------- -----------------------------
Web Assembly: Baseline   1'041 µs/iter     (978 µs … 1'757 µs)  1'035 µs  1'605 µs  1'757 µs
Web Assembly: Latest     1'396 µs/iter   (1'317 µs … 2'170 µs)  1'387 µs  2'008 µs  2'170 µs
Web Assembly: Current    1'357 µs/iter   (1'292 µs … 2'184 µs)  1'361 µs  1'821 µs  2'184 µs
Node API: Current          757 µs/iter     (706 µs … 1'082 µs)    780 µs    829 µs  1'082 µs

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

• movie.findMany({ where: { cast: { person: { ... } }, take: 100 }) (m2m -> to-one)
-------------------------------------------------------------- -----------------------------
Web Assembly: Baseline   1'024 µs/iter     (982 µs … 1'714 µs)  1'029 µs  1'362 µs  1'714 µs
Web Assembly: Latest     1'407 µs/iter   (1'298 µs … 2'584 µs)  1'371 µs  2'563 µs  2'584 µs
Web Assembly: Current    1'379 µs/iter   (1'318 µs … 2'007 µs)  1'377 µs  1'760 µs  2'007 µs
Node API: Current          753 µs/iter     (707 µs … 1'076 µs)    773 µs    863 µs  1'076 µs

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

After changes in 10b8db3

Copy link
Contributor

@Weakky Weakky left a comment

Choose a reason for hiding this comment

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

:chef-kiss: ! See my comment, I'll leave you to decide what you think's best 👍

@laplab laplab added this to the 5.13.0 milestone Apr 11, 2024
@laplab laplab merged commit 6d35870 into main Apr 11, 2024
182 checks passed
@laplab laplab deleted the fix/expression-formatting branch April 11, 2024 13:30
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