diff --git a/.github/workflows/cqn4sql-benchmarks.yml b/.github/workflows/cqn4sql-benchmarks.yml new file mode 100644 index 000000000..0c20c6ba2 --- /dev/null +++ b/.github/workflows/cqn4sql-benchmarks.yml @@ -0,0 +1,60 @@ +name: cqn4sql benchmarks + visualization + +on: + push: + branches: [ patrice/cds-test-perfomance ] + workflow_dispatch: + +permissions: + contents: read + pages: write + id-token: write + +concurrency: + group: "pages" + cancel-in-progress: true + +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 1 + + - name: Setup Node + uses: actions/setup-node@v4 + with: + node-version: 20 + cache: npm + + - name: Install dependencies + run: npm ci + + # this needs the cds-test PR to be merged first + # - name: Run benchmarks + # run: | + # cd ./db-service/bench/cqn4sql && CDS_BENCH=true cds test + + - name: Build visualization + run: | + cd ./db-service/bench/cqn4sql + mkdir -p dist + node utils/visualize-benchmarks.js results/cqn4sql-benchmarks.json dist/index.html + + - name: Upload Pages artifact + uses: actions/upload-pages-artifact@v3 + with: + path: ./db-service/bench/cqn4sql/dist + + deploy: + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + needs: build + runs-on: ubuntu-latest + steps: + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v4 diff --git a/db-service/bench/cqn4sql/model/schema.cds b/db-service/bench/cqn4sql/model/schema.cds new file mode 100644 index 000000000..52d2ef78c --- /dev/null +++ b/db-service/bench/cqn4sql/model/schema.cds @@ -0,0 +1,34 @@ +namespace my; + +entity Books { + key ID : Integer; + title : String; + stock : Integer; + author : Association to Authors; + genre : Association to Genres; +} + +entity BooksWithCalc : Books { + authorFullName = author.firstName || ' ' || author.lastName; +} + +entity Authors { + key ID : Integer; + firstName : String; + lastName : String; + dateOfBirth : Date; + dateOfDeath : Date; + books : Association to many Books + on books.author = $self; +} + +@cds.search: { books } +entity AuthorsSearchBooks : Authors {} + +entity Genres { + key ID : Integer; + name : String; + parent : Association to Genres; + children : Composition of many Genres + on children.parent = $self; +} diff --git a/db-service/bench/cqn4sql/performance-benchmarks.test.js b/db-service/bench/cqn4sql/performance-benchmarks.test.js new file mode 100644 index 000000000..67a333c93 --- /dev/null +++ b/db-service/bench/cqn4sql/performance-benchmarks.test.js @@ -0,0 +1,66 @@ +'use strict' + +if (process.env.CDS_BENCH === 'true') { + const cds = require('@sap/cds') + const { writeDump } = require('./utils/format-benchmarks') + + let cqn4sql = require('../../lib/cqn4sql') + + const { + perf, + } = cds.test + + const report = (what, options) => perf.report(what, { store: true, stats: { requests: true }, ...options }) + + describe('cqn4sql performance benchmarks', () => { + beforeEach(async () => { + const m = await cds.load([__dirname + '/model/schema']).then(cds.linked) + const orig = cqn4sql // keep reference to original to avoid recursion + cqn4sql = q => orig(q, m) + }) + + after('format & write dump', () => { + writeDump({ testFile: __filename }) + }) + + runBenchmarkFor('select simple', cds.ql`SELECT from my.Books { ID }`) + + runBenchmarkFor('select wildcard', cds.ql`SELECT from my.Books { * }`) + runBenchmarkFor('select wildcard with calculated element', cds.ql`SELECT from my.BooksWithCalc { * }`) + + runBenchmarkFor('expand simple', cds.ql`SELECT from my.Authors { ID, books { title } }`) + runBenchmarkFor('expand recursive (depth 3)', cds.ql`SELECT from my.Genres { ID, parent { parent { parent { name }}} }`) + + runBenchmarkFor('exists simple', cds.ql`SELECT from my.Genres { ID } where exists parent`) + runBenchmarkFor('exists simple with path expression', cds.ql`SELECT from my.Genres { ID } where exists parent[parent.name = 'foo']`) + runBenchmarkFor('exists recursive (depth 3)', cds.ql`SELECT from my.Genres { ID } where exists parent.parent.parent`) + + runBenchmarkFor('assoc2join simple', cds.ql`SELECT from my.Books { ID, author.firstName }`) + runBenchmarkFor('assoc2join recursive (depth 3)', cds.ql`SELECT from my.Genres { ID, parent.parent.parent.name }`) + + runBenchmarkFor('@cds.search simple', SELECT.from('my.Authors').columns('ID', 'firstName', 'lastName').search('Tolkien')) + runBenchmarkFor('@cds.search deep', SELECT.from('my.AuthorsSearchBooks').columns('ID', 'firstName', 'lastName').search('The Lord of the Rings')) + + runBenchmarkFor('scoped query', cds.ql`SELECT from my.Books:author { name }`) + }) + + + function runBenchmarkFor(name, cqn) { + it(name, async () => + report( + await perf.fn( + () => { + cqn4sql(cqn) + }, + { + title: name, + warmup: { + duration: '3s', + }, + duration: '10s', + }, + ), + ), + ) + } +} diff --git a/db-service/bench/cqn4sql/results/cqn4sql-benchmarks.json b/db-service/bench/cqn4sql/results/cqn4sql-benchmarks.json new file mode 100644 index 000000000..8e1d0828b --- /dev/null +++ b/db-service/bench/cqn4sql/results/cqn4sql-benchmarks.json @@ -0,0 +1 @@ +{"8ea5c2b9":{"date":"2025-08-27T15:03:45.583Z","benchmarks":{"select simple":{"average":87328,"mean":87328,"stddev":64,"min":87254,"max":87407,"total":262221,"p0_001":87295,"p0_01":87295,"p0_1":87295,"p1":87295,"p2_5":87295,"p10":87295,"p25":87295,"p50":87295,"p75":87423,"p90":87423,"p97_5":87423,"p99":87423,"p99_9":87423,"p99_99":87423,"p99_999":87423,"sent":262221},"expand simple":{"average":20440,"mean":20440,"stddev":608,"min":19829,"max":21042,"total":61476,"p0_001":19839,"p0_01":19839,"p0_1":19839,"p1":19839,"p2_5":19839,"p10":19839,"p25":19839,"p50":19839,"p75":21055,"p90":21055,"p97_5":21055,"p99":21055,"p99_9":21055,"p99_99":21055,"p99_999":21055,"sent":61476},"expand recursive (depth 3)":{"average":7926,"mean":7926,"stddev":252,"min":7673,"max":8176,"total":23912,"p0_001":7675,"p0_01":7675,"p0_1":7675,"p1":7675,"p2_5":7675,"p10":7675,"p25":7675,"p50":7675,"p75":8179,"p90":8179,"p97_5":8179,"p99":8179,"p99_9":8179,"p99_99":8179,"p99_999":8179,"sent":23912},"exists simple":{"average":8144,"mean":8144,"stddev":26,"min":8117,"max":8168,"total":24353,"p0_001":8119,"p0_01":8119,"p0_1":8119,"p1":8119,"p2_5":8119,"p10":8119,"p25":8119,"p50":8119,"p75":8171,"p90":8171,"p97_5":8171,"p99":8171,"p99_9":8171,"p99_99":8171,"p99_999":8171,"sent":24353},"exists recursive (depth 3)":{"average":46192,"mean":46192,"stddev":224,"min":45979,"max":46426,"total":139422,"p0_001":45983,"p0_01":45983,"p0_1":45983,"p1":45983,"p2_5":45983,"p10":45983,"p25":45983,"p50":45983,"p75":46431,"p90":46431,"p97_5":46431,"p99":46431,"p99_9":46431,"p99_99":46431,"p99_999":46431,"sent":139422},"assoc2join simple":{"average":53792,"mean":53792,"stddev":1328,"min":52462,"max":55129,"total":159915,"p0_001":52479,"p0_01":52479,"p0_1":52479,"p1":52479,"p2_5":52479,"p10":52479,"p25":52479,"p50":52479,"p75":55135,"p90":55135,"p97_5":55135,"p99":55135,"p99_9":55135,"p99_99":55135,"p99_999":55135,"sent":159915},"assoc2join recursive (depth 3)":{"average":42480,"mean":42480,"stddev":384,"min":42091,"max":42872,"total":128504,"p0_001":42111,"p0_01":42111,"p0_1":42111,"p1":42111,"p2_5":42111,"p10":42111,"p25":42111,"p50":42111,"p75":42879,"p90":42879,"p97_5":42879,"p99":42879,"p99_9":42879,"p99_99":42879,"p99_999":42879,"sent":128504}}},"19731f02":{"date":"2025-08-27T15:06:07.491Z","benchmarks":{"select simple":{"average":87520,"mean":87520,"stddev":768,"min":86776,"max":88269,"total":262842,"p0_001":86783,"p0_01":86783,"p0_1":86783,"p1":86783,"p2_5":86783,"p10":86783,"p25":86783,"p50":86783,"p75":88319,"p90":88319,"p97_5":88319,"p99":88319,"p99_9":88319,"p99_99":88319,"p99_999":88319,"sent":262842},"expand simple":{"average":20016,"mean":20016,"stddev":376,"min":19641,"max":20392,"total":60756,"p0_001":19647,"p0_01":19647,"p0_1":19647,"p1":19647,"p2_5":19647,"p10":19647,"p25":19647,"p50":19647,"p75":20399,"p90":20399,"p97_5":20399,"p99":20399,"p99_9":20399,"p99_99":20399,"p99_999":20399,"sent":60756},"expand recursive (depth 3)":{"average":8123,"mean":8123,"stddev":145,"min":7979,"max":8269,"total":24649,"p0_001":7979,"p0_01":7979,"p0_1":7979,"p1":7979,"p2_5":7979,"p10":7979,"p25":7979,"p50":7979,"p75":8271,"p90":8271,"p97_5":8271,"p99":8271,"p99_9":8271,"p99_99":8271,"p99_999":8271,"sent":24649},"exists simple":{"average":8352,"mean":8352,"stddev":36,"min":8319,"max":8384,"total":25059,"p0_001":8319,"p0_01":8319,"p0_1":8319,"p1":8319,"p2_5":8319,"p10":8319,"p25":8319,"p50":8319,"p75":8391,"p90":8391,"p97_5":8391,"p99":8391,"p99_9":8391,"p99_99":8391,"p99_999":8391,"sent":25059},"exists recursive (depth 3)":{"average":46080,"mean":46080,"stddev":528,"min":45565,"max":46621,"total":139483,"p0_001":45567,"p0_01":45567,"p0_1":45567,"p1":45567,"p2_5":45567,"p10":45567,"p25":45567,"p50":45567,"p75":46623,"p90":46623,"p97_5":46623,"p99":46623,"p99_9":46623,"p99_99":46623,"p99_999":46623,"sent":139483},"assoc2join simple":{"average":54800,"mean":54800,"stddev":288,"min":54505,"max":55102,"total":164553,"p0_001":54527,"p0_01":54527,"p0_1":54527,"p1":54527,"p2_5":54527,"p10":54527,"p25":54527,"p50":54527,"p75":55103,"p90":55103,"p97_5":55103,"p99":55103,"p99_9":55103,"p99_99":55103,"p99_999":55103,"sent":164553},"assoc2join recursive (depth 3)":{"average":45888,"mean":45888,"stddev":80,"min":45799,"max":45980,"total":137312,"p0_001":45823,"p0_01":45823,"p0_1":45823,"p1":45823,"p2_5":45823,"p10":45823,"p25":45823,"p50":45823,"p75":45983,"p90":45983,"p97_5":45983,"p99":45983,"p99_9":45983,"p99_99":45983,"p99_999":45983,"sent":137312}}},"95c3b619":{"date":"2025-08-27T15:21:15.094Z","benchmarks":{"select simple":{"average":88224,"mean":88224,"stddev":256,"min":87958,"max":88496,"total":264485,"p0_001":87999,"p0_01":87999,"p0_1":87999,"p1":87999,"p2_5":87999,"p10":87999,"p25":87999,"p50":87999,"p75":88511,"p90":88511,"p97_5":88511,"p99":88511,"p99_9":88511,"p99_99":88511,"p99_999":88511,"sent":264485},"expand simple":{"average":20280,"mean":20280,"stddev":320,"min":19963,"max":20592,"total":61170,"p0_001":19967,"p0_01":19967,"p0_1":19967,"p1":19967,"p2_5":19967,"p10":19967,"p25":19967,"p50":19967,"p75":20607,"p90":20607,"p97_5":20607,"p99":20607,"p99_9":20607,"p99_99":20607,"p99_999":20607,"sent":61170},"expand recursive (depth 3)":{"average":8213,"mean":8213,"stddev":199,"min":8012,"max":8409,"total":24668,"p0_001":8015,"p0_01":8015,"p0_1":8015,"p1":8015,"p2_5":8015,"p10":8015,"p25":8015,"p50":8015,"p75":8415,"p90":8415,"p97_5":8415,"p99":8415,"p99_9":8415,"p99_99":8415,"p99_999":8415,"sent":24668},"exists simple":{"average":8199,"mean":8199,"stddev":181,"min":8017,"max":8377,"total":24403,"p0_001":8019,"p0_01":8019,"p0_1":8019,"p1":8019,"p2_5":8019,"p10":8019,"p25":8019,"p50":8019,"p75":8383,"p90":8383,"p97_5":8383,"p99":8383,"p99_9":8383,"p99_99":8383,"p99_999":8383,"sent":24403},"exists recursive (depth 3)":{"average":45408,"mean":45408,"stddev":144,"min":45256,"max":45553,"total":137346,"p0_001":45279,"p0_01":45279,"p0_1":45279,"p1":45279,"p2_5":45279,"p10":45279,"p25":45279,"p50":45279,"p75":45567,"p90":45567,"p97_5":45567,"p99":45567,"p99_9":45567,"p99_99":45567,"p99_999":45567,"sent":137346},"assoc2join simple":{"average":53680,"mean":53680,"stddev":288,"min":53400,"max":53983,"total":162826,"p0_001":53407,"p0_01":53407,"p0_1":53407,"p1":53407,"p2_5":53407,"p10":53407,"p25":53407,"p50":53407,"p75":53983,"p90":53983,"p97_5":53983,"p99":53983,"p99_9":53983,"p99_99":53983,"p99_999":53983,"sent":162826},"assoc2join recursive (depth 3)":{"average":45600,"mean":45600,"stddev":16,"min":45589,"max":45628,"total":134677,"p0_001":45599,"p0_01":45599,"p0_1":45599,"p1":45599,"p2_5":45599,"p10":45599,"p25":45599,"p50":45599,"p75":45631,"p90":45631,"p97_5":45631,"p99":45631,"p99_9":45631,"p99_99":45631,"p99_999":45631,"sent":134677}}},"0d15c979":{"date":"2025-08-27T15:47:11.987Z","benchmarks":{"select simple":{"average":87808,"mean":87808,"stddev":288,"min":87523,"max":88103,"total":262013,"p0_001":87551,"p0_01":87551,"p0_1":87551,"p1":87551,"p2_5":87551,"p10":87551,"p25":87551,"p50":87551,"p75":88127,"p90":88127,"p97_5":88127,"p99":88127,"p99_9":88127,"p99_99":88127,"p99_999":88127,"sent":262013},"expand simple":{"average":20184,"mean":20184,"stddev":144,"min":20047,"max":20320,"total":61287,"p0_001":20047,"p0_01":20047,"p0_1":20047,"p1":20047,"p2_5":20047,"p10":20047,"p25":20047,"p50":20047,"p75":20335,"p90":20335,"p97_5":20335,"p99":20335,"p99_9":20335,"p99_99":20335,"p99_999":20335,"sent":61287},"expand recursive (depth 3)":{"average":8088,"mean":8088,"stddev":22,"min":8065,"max":8111,"total":24410,"p0_001":8067,"p0_01":8067,"p0_1":8067,"p1":8067,"p2_5":8067,"p10":8067,"p25":8067,"p50":8067,"p75":8111,"p90":8111,"p97_5":8111,"p99":8111,"p99_9":8111,"p99_99":8111,"p99_999":8111,"sent":24410},"exists simple":{"average":59616,"mean":59616,"stddev":144,"min":59475,"max":59758,"total":178296,"p0_001":59487,"p0_01":59487,"p0_1":59487,"p1":59487,"p2_5":59487,"p10":59487,"p25":59487,"p50":59487,"p75":59775,"p90":59775,"p97_5":59775,"p99":59775,"p99_9":59775,"p99_99":59775,"p99_999":59775,"sent":178296},"exists recursive (depth 3)":{"average":45376,"mean":45376,"stddev":528,"min":44854,"max":45917,"total":136505,"p0_001":44863,"p0_01":44863,"p0_1":44863,"p1":44863,"p2_5":44863,"p10":44863,"p25":44863,"p50":44863,"p75":45919,"p90":45919,"p97_5":45919,"p99":45919,"p99_9":45919,"p99_99":45919,"p99_999":45919,"sent":136505},"assoc2join simple":{"average":52080,"mean":52080,"stddev":960,"min":51120,"max":53037,"total":158696,"p0_001":51135,"p0_01":51135,"p0_1":51135,"p1":51135,"p2_5":51135,"p10":51135,"p25":51135,"p50":51135,"p75":53055,"p90":53055,"p97_5":53055,"p99":53055,"p99_9":53055,"p99_99":53055,"p99_999":53055,"sent":158696},"assoc2join recursive (depth 3)":{"average":45984,"mean":45984,"stddev":240,"min":45749,"max":46210,"total":136546,"p0_001":45759,"p0_01":45759,"p0_1":45759,"p1":45759,"p2_5":45759,"p10":45759,"p25":45759,"p50":45759,"p75":46239,"p90":46239,"p97_5":46239,"p99":46239,"p99_9":46239,"p99_99":46239,"p99_999":46239,"sent":136546}}},"c8575c73":{"date":"2025-08-27T15:47:51.334Z","benchmarks":{"select simple":{"average":87200,"mean":87200,"stddev":256,"min":86930,"max":87459,"total":262459,"p0_001":86975,"p0_01":86975,"p0_1":86975,"p1":86975,"p2_5":86975,"p10":86975,"p25":86975,"p50":86975,"p75":87487,"p90":87487,"p97_5":87487,"p99":87487,"p99_9":87487,"p99_99":87487,"p99_999":87487,"sent":262459},"expand simple":{"average":20288,"mean":20288,"stddev":440,"min":19845,"max":20725,"total":61279,"p0_001":19855,"p0_01":19855,"p0_1":19855,"p1":19855,"p2_5":19855,"p10":19855,"p25":19855,"p50":19855,"p75":20735,"p90":20735,"p97_5":20735,"p99":20735,"p99_9":20735,"p99_99":20735,"p99_999":20735,"sent":61279},"expand recursive (depth 3)":{"average":8219,"mean":8219,"stddev":49,"min":8171,"max":8268,"total":24486,"p0_001":8171,"p0_01":8171,"p0_1":8171,"p1":8171,"p2_5":8171,"p10":8171,"p25":8171,"p50":8171,"p75":8271,"p90":8271,"p97_5":8271,"p99":8271,"p99_9":8271,"p99_99":8271,"p99_999":8271,"sent":24486},"exists simple":{"average":59952,"mean":59952,"stddev":128,"min":59836,"max":60091,"total":181216,"p0_001":59839,"p0_01":59839,"p0_1":59839,"p1":59839,"p2_5":59839,"p10":59839,"p25":59839,"p50":59839,"p75":60095,"p90":60095,"p97_5":60095,"p99":60095,"p99_9":60095,"p99_99":60095,"p99_999":60095,"sent":181216},"exists recursive (depth 3)":{"average":45520,"mean":45520,"stddev":320,"min":45211,"max":45855,"total":137895,"p0_001":45215,"p0_01":45215,"p0_1":45215,"p1":45215,"p2_5":45215,"p10":45215,"p25":45215,"p50":45215,"p75":45855,"p90":45855,"p97_5":45855,"p99":45855,"p99_9":45855,"p99_99":45855,"p99_999":45855,"sent":137895},"assoc2join simple":{"average":52816,"mean":52816,"stddev":96,"min":52722,"max":52917,"total":160611,"p0_001":52735,"p0_01":52735,"p0_1":52735,"p1":52735,"p2_5":52735,"p10":52735,"p25":52735,"p50":52735,"p75":52927,"p90":52927,"p97_5":52927,"p99":52927,"p99_9":52927,"p99_99":52927,"p99_999":52927,"sent":160611},"assoc2join recursive (depth 3)":{"average":45456,"mean":45456,"stddev":352,"min":45100,"max":45816,"total":133427,"p0_001":45119,"p0_01":45119,"p0_1":45119,"p1":45119,"p2_5":45119,"p10":45119,"p25":45119,"p50":45119,"p75":45823,"p90":45823,"p97_5":45823,"p99":45823,"p99_9":45823,"p99_99":45823,"p99_999":45823,"sent":133427}}},"b1185062":{"date":"2025-08-27T15:50:34.031Z","benchmarks":{"select simple":{"average":87008,"mean":87008,"stddev":384,"min":86614,"max":87398,"total":259344,"p0_001":86655,"p0_01":86655,"p0_1":86655,"p1":86655,"p2_5":86655,"p10":86655,"p25":86655,"p50":86655,"p75":87423,"p90":87423,"p97_5":87423,"p99":87423,"p99_9":87423,"p99_99":87423,"p99_999":87423,"sent":259344},"expand simple":{"average":20216,"mean":20216,"stddev":96,"min":20115,"max":20306,"total":60190,"p0_001":20127,"p0_01":20127,"p0_1":20127,"p1":20127,"p2_5":20127,"p10":20127,"p25":20127,"p50":20127,"p75":20319,"p90":20319,"p97_5":20319,"p99":20319,"p99_9":20319,"p99_99":20319,"p99_999":20319,"sent":60190},"expand recursive (depth 3)":{"average":8236,"mean":8236,"stddev":32,"min":8204,"max":8268,"total":24484,"p0_001":8207,"p0_01":8207,"p0_1":8207,"p1":8207,"p2_5":8207,"p10":8207,"p25":8207,"p50":8207,"p75":8271,"p90":8271,"p97_5":8271,"p99":8271,"p99_9":8271,"p99_99":8271,"p99_999":8271,"sent":24484},"exists simple":{"average":57360,"mean":57360,"stddev":864,"min":56504,"max":58228,"total":173453,"p0_001":56511,"p0_01":56511,"p0_1":56511,"p1":56511,"p2_5":56511,"p10":56511,"p25":56511,"p50":56511,"p75":58239,"p90":58239,"p97_5":58239,"p99":58239,"p99_9":58239,"p99_99":58239,"p99_999":58239,"sent":173453},"exists recursive (depth 3)":{"average":45856,"mean":45856,"stddev":528,"min":45323,"max":46370,"total":137136,"p0_001":45343,"p0_01":45343,"p0_1":45343,"p1":45343,"p2_5":45343,"p10":45343,"p25":45343,"p50":45343,"p75":46399,"p90":46399,"p97_5":46399,"p99":46399,"p99_9":46399,"p99_99":46399,"p99_999":46399,"sent":137136},"assoc2join simple":{"average":53520,"mean":53520,"stddev":480,"min":53051,"max":53988,"total":159217,"p0_001":53055,"p0_01":53055,"p0_1":53055,"p1":53055,"p2_5":53055,"p10":53055,"p25":53055,"p50":53055,"p75":54015,"p90":54015,"p97_5":54015,"p99":54015,"p99_9":54015,"p99_99":54015,"p99_999":54015,"sent":159217},"assoc2join recursive (depth 3)":{"average":45232,"mean":45232,"stddev":640,"min":44580,"max":45879,"total":136285,"p0_001":44607,"p0_01":44607,"p0_1":44607,"p1":44607,"p2_5":44607,"p10":44607,"p25":44607,"p50":44607,"p75":45887,"p90":45887,"p97_5":45887,"p99":45887,"p99_9":45887,"p99_99":45887,"p99_999":45887,"sent":136285}}},"661cb21d":{"date":"2025-08-27T15:53:50.826Z","benchmarks":{"select simple":{"average":85984,"mean":85984,"stddev":2304,"min":83700,"max":88317,"total":258747,"p0_001":83711,"p0_01":83711,"p0_1":83711,"p1":83711,"p2_5":83711,"p10":83711,"p25":83711,"p50":83711,"p75":88319,"p90":88319,"p97_5":88319,"p99":88319,"p99_9":88319,"p99_99":88319,"p99_999":88319,"sent":258747},"expand simple":{"average":20370.67,"mean":20370.67,"stddev":517.04,"min":19638,"max":20766,"total":61110,"p0_001":19647,"p0_01":19647,"p0_1":19647,"p1":19647,"p2_5":19647,"p10":19647,"p25":19647,"p50":20719,"p75":20767,"p90":20767,"p97_5":20767,"p99":20767,"p99_9":20767,"p99_99":20767,"p99_999":20767,"sent":61110},"expand recursive (depth 3)":{"average":8221,"mean":8221,"stddev":47,"min":8172,"max":8266,"total":24695,"p0_001":8175,"p0_01":8175,"p0_1":8175,"p1":8175,"p2_5":8175,"p10":8175,"p25":8175,"p50":8175,"p75":8271,"p90":8271,"p97_5":8271,"p99":8271,"p99_9":8271,"p99_99":8271,"p99_999":8271,"sent":24695},"exists simple":{"average":59328,"mean":59328,"stddev":624,"min":58704,"max":59956,"total":177818,"p0_001":58719,"p0_01":58719,"p0_1":58719,"p1":58719,"p2_5":58719,"p10":58719,"p25":58719,"p50":58719,"p75":59967,"p90":59967,"p97_5":59967,"p99":59967,"p99_9":59967,"p99_99":59967,"p99_999":59967,"sent":177818},"exists recursive (depth 3)":{"average":46725.34,"mean":46725.34,"stddev":510.89,"min":46032,"max":47245,"total":140188,"p0_001":46047,"p0_01":46047,"p0_1":46047,"p1":46047,"p2_5":46047,"p10":46047,"p25":46047,"p50":46911,"p75":47263,"p90":47263,"p97_5":47263,"p99":47263,"p99_9":47263,"p99_99":47263,"p99_999":47263,"sent":140188},"assoc2join simple":{"average":53856,"mean":53856,"stddev":16,"min":53826,"max":53885,"total":162938,"p0_001":53855,"p0_01":53855,"p0_1":53855,"p1":53855,"p2_5":53855,"p10":53855,"p25":53855,"p50":53855,"p75":53887,"p90":53887,"p97_5":53887,"p99":53887,"p99_9":53887,"p99_99":53887,"p99_999":53887,"sent":162938},"assoc2join recursive (depth 3)":{"average":45984,"mean":45984,"stddev":272,"min":45714,"max":46240,"total":136085,"p0_001":45727,"p0_01":45727,"p0_1":45727,"p1":45727,"p2_5":45727,"p10":45727,"p25":45727,"p50":45727,"p75":46271,"p90":46271,"p97_5":46271,"p99":46271,"p99_9":46271,"p99_99":46271,"p99_999":46271,"sent":136085}}},"894466ad":{"date":"2025-08-27T15:55:43.622Z","benchmarks":{"select simple":{"average":89216,"mean":89216,"stddev":416,"min":88807,"max":89641,"total":266546,"p0_001":88831,"p0_01":88831,"p0_1":88831,"p1":88831,"p2_5":88831,"p10":88831,"p25":88831,"p50":88831,"p75":89663,"p90":89663,"p97_5":89663,"p99":89663,"p99_9":89663,"p99_99":89663,"p99_999":89663,"sent":266546},"expand simple":{"average":20648,"mean":20648,"stddev":528,"min":20121,"max":21171,"total":62540,"p0_001":20127,"p0_01":20127,"p0_1":20127,"p1":20127,"p2_5":20127,"p10":20127,"p25":20127,"p50":20127,"p75":21183,"p90":21183,"p97_5":21183,"p99":21183,"p99_9":21183,"p99_99":21183,"p99_999":21183,"sent":62540},"expand recursive (depth 3)":{"average":8416,"mean":8416,"stddev":4,"min":8415,"max":8419,"total":25342,"p0_001":8415,"p0_01":8415,"p0_1":8415,"p1":8415,"p2_5":8415,"p10":8415,"p25":8415,"p50":8415,"p75":8423,"p90":8423,"p97_5":8423,"p99":8423,"p99_9":8423,"p99_99":8423,"p99_999":8423,"sent":25342},"exists simple":{"average":59008,"mean":59008,"stddev":720,"min":58282,"max":59733,"total":177942,"p0_001":58303,"p0_01":58303,"p0_1":58303,"p1":58303,"p2_5":58303,"p10":58303,"p25":58303,"p50":58303,"p75":59743,"p90":59743,"p97_5":59743,"p99":59743,"p99_9":59743,"p99_99":59743,"p99_999":59743,"sent":177942},"exists recursive (depth 3)":{"average":45728,"mean":45728,"stddev":176,"min":45538,"max":45902,"total":137503,"p0_001":45567,"p0_01":45567,"p0_1":45567,"p1":45567,"p2_5":45567,"p10":45567,"p25":45567,"p50":45567,"p75":45919,"p90":45919,"p97_5":45919,"p99":45919,"p99_9":45919,"p99_99":45919,"p99_999":45919,"sent":137503},"assoc2join simple":{"average":53888,"mean":53888,"stddev":304,"min":53593,"max":54197,"total":162411,"p0_001":53599,"p0_01":53599,"p0_1":53599,"p1":53599,"p2_5":53599,"p10":53599,"p25":53599,"p50":53599,"p75":54207,"p90":54207,"p97_5":54207,"p99":54207,"p99_9":54207,"p99_99":54207,"p99_999":54207,"sent":162411},"assoc2join recursive (depth 3)":{"average":46080,"mean":46080,"stddev":144,"min":45944,"max":46232,"total":138192,"p0_001":45951,"p0_01":45951,"p0_1":45951,"p1":45951,"p2_5":45951,"p10":45951,"p25":45951,"p50":45951,"p75":46239,"p90":46239,"p97_5":46239,"p99":46239,"p99_9":46239,"p99_99":46239,"p99_999":46239,"sent":138192}}},"8ef8958b":{"date":"2025-08-27T16:09:15.187Z","benchmarks":{"select simple":{"average":89536,"mean":89536,"stddev":224,"min":89314,"max":89782,"total":269236,"p0_001":89343,"p0_01":89343,"p0_1":89343,"p1":89343,"p2_5":89343,"p10":89343,"p25":89343,"p50":89343,"p75":89791,"p90":89791,"p97_5":89791,"p99":89791,"p99_9":89791,"p99_99":89791,"p99_999":89791,"sent":269236},"expand simple":{"average":20264,"mean":20264,"stddev":704,"min":19567,"max":20967,"total":61689,"p0_001":19567,"p0_01":19567,"p0_1":19567,"p1":19567,"p2_5":19567,"p10":19567,"p25":19567,"p50":19567,"p75":20975,"p90":20975,"p97_5":20975,"p99":20975,"p99_9":20975,"p99_99":20975,"p99_999":20975,"sent":61689},"expand recursive (depth 3)":{"average":8179,"mean":8179,"stddev":137,"min":8042,"max":8316,"total":24638,"p0_001":8043,"p0_01":8043,"p0_1":8043,"p1":8043,"p2_5":8043,"p10":8043,"p25":8043,"p50":8043,"p75":8319,"p90":8319,"p97_5":8319,"p99":8319,"p99_9":8319,"p99_99":8319,"p99_999":8319,"sent":24638},"exists simple":{"average":60560,"mean":60560,"stddev":320,"min":60246,"max":60874,"total":178901,"p0_001":60255,"p0_01":60255,"p0_1":60255,"p1":60255,"p2_5":60255,"p10":60255,"p25":60255,"p50":60255,"p75":60895,"p90":60895,"p97_5":60895,"p99":60895,"p99_9":60895,"p99_99":60895,"p99_999":60895,"sent":178901},"exists simple with path expression":{"average":22560,"mean":22560,"stddev":344,"min":22220,"max":22902,"total":67606,"p0_001":22223,"p0_01":22223,"p0_1":22223,"p1":22223,"p2_5":22223,"p10":22223,"p25":22223,"p50":22223,"p75":22911,"p90":22911,"p97_5":22911,"p99":22911,"p99_9":22911,"p99_99":22911,"p99_999":22911,"sent":67606},"exists recursive (depth 3)":{"average":41888,"mean":41888,"stddev":16,"min":41871,"max":41898,"total":127501,"p0_001":41887,"p0_01":41887,"p0_1":41887,"p1":41887,"p2_5":41887,"p10":41887,"p25":41887,"p50":41887,"p75":41919,"p90":41919,"p97_5":41919,"p99":41919,"p99_9":41919,"p99_99":41919,"p99_999":41919,"sent":127501},"assoc2join simple":{"average":52960,"mean":52960,"stddev":784,"min":52162,"max":53755,"total":156900,"p0_001":52191,"p0_01":52191,"p0_1":52191,"p1":52191,"p2_5":52191,"p10":52191,"p25":52191,"p50":52191,"p75":53759,"p90":53759,"p97_5":53759,"p99":53759,"p99_9":53759,"p99_99":53759,"p99_999":53759,"sent":156900},"assoc2join recursive (depth 3)":{"average":44128,"mean":44128,"stddev":656,"min":43473,"max":44797,"total":132577,"p0_001":43487,"p0_01":43487,"p0_1":43487,"p1":43487,"p2_5":43487,"p10":43487,"p25":43487,"p50":43487,"p75":44799,"p90":44799,"p97_5":44799,"p99":44799,"p99_9":44799,"p99_99":44799,"p99_999":44799,"sent":132577}}},"589006ca":{"date":"2025-08-27T16:51:33.834Z","benchmarks":{"select simple":{"average":88736,"mean":88736,"stddev":832,"min":87931,"max":89539,"total":266153,"p0_001":87935,"p0_01":87935,"p0_1":87935,"p1":87935,"p2_5":87935,"p10":87935,"p25":87935,"p50":87935,"p75":89599,"p90":89599,"p97_5":89599,"p99":89599,"p99_9":89599,"p99_99":89599,"p99_999":89599,"sent":266153},"expand simple":{"average":20176,"mean":20176,"stddev":360,"min":19820,"max":20536,"total":61070,"p0_001":19823,"p0_01":19823,"p0_1":19823,"p1":19823,"p2_5":19823,"p10":19823,"p25":19823,"p50":19823,"p75":20543,"p90":20543,"p97_5":20543,"p99":20543,"p99_9":20543,"p99_99":20543,"p99_999":20543,"sent":61070},"expand recursive (depth 3)":{"average":8213,"mean":8213,"stddev":119,"min":8095,"max":8335,"total":24564,"p0_001":8095,"p0_01":8095,"p0_1":8095,"p1":8095,"p2_5":8095,"p10":8095,"p25":8095,"p50":8095,"p75":8335,"p90":8335,"p97_5":8335,"p99":8335,"p99_9":8335,"p99_99":8335,"p99_999":8335,"sent":24564},"exists simple":{"average":59808,"mean":59808,"stddev":816,"min":58977,"max":60620,"total":179837,"p0_001":59007,"p0_01":59007,"p0_1":59007,"p1":59007,"p2_5":59007,"p10":59007,"p25":59007,"p50":59007,"p75":60639,"p90":60639,"p97_5":60639,"p99":60639,"p99_9":60639,"p99_99":60639,"p99_999":60639,"sent":179837},"exists simple with path expression":{"average":23472,"mean":23472,"stddev":8,"min":23471,"max":23478,"total":70623,"p0_001":23471,"p0_01":23471,"p0_1":23471,"p1":23471,"p2_5":23471,"p10":23471,"p25":23471,"p50":23471,"p75":23487,"p90":23487,"p97_5":23487,"p99":23487,"p99_9":23487,"p99_99":23487,"p99_999":23487,"sent":70623},"exists recursive (depth 3)":{"average":42112,"mean":42112,"stddev":720,"min":41377,"max":42833,"total":126500,"p0_001":41407,"p0_01":41407,"p0_1":41407,"p1":41407,"p2_5":41407,"p10":41407,"p25":41407,"p50":41407,"p75":42847,"p90":42847,"p97_5":42847,"p99":42847,"p99_9":42847,"p99_99":42847,"p99_999":42847,"sent":126500},"assoc2join simple":{"average":52768,"mean":52768,"stddev":1552,"min":51214,"max":54312,"total":145122,"p0_001":51231,"p0_01":51231,"p0_1":51231,"p1":51231,"p2_5":51231,"p10":51231,"p25":51231,"p50":51231,"p75":54335,"p90":54335,"p97_5":54335,"p99":54335,"p99_9":54335,"p99_99":54335,"p99_999":54335,"sent":145122},"assoc2join recursive (depth 3)":{"average":45296,"mean":45296,"stddev":128,"min":45177,"max":45433,"total":136314,"p0_001":45183,"p0_01":45183,"p0_1":45183,"p1":45183,"p2_5":45183,"p10":45183,"p25":45183,"p50":45183,"p75":45439,"p90":45439,"p97_5":45439,"p99":45439,"p99_9":45439,"p99_99":45439,"p99_999":45439,"sent":136314}}},"f31fbb68":{"date":"2025-08-28T09:34:23.170Z","benchmarks":{"select simple":{"total":829228,"mean":85436.45,"min":83675,"max":87021,"stddev":995.66,"p50":85503,"p90":87039,"p99":87039},"select wildcard":{"total":751781,"mean":76042.67,"min":73635,"max":77921,"stddev":1059.82,"p50":76287,"p90":77951,"p99":77951},"select wildcard with calculated element":{"total":330054,"mean":33055.12,"min":31731,"max":33651,"stddev":605.63,"p50":33247,"p90":33663,"p99":33663},"expand simple":{"total":204523,"mean":20441.78,"min":20254,"max":20534,"stddev":87.46,"p50":20479,"p90":20543,"p99":20543},"expand recursive (depth 3)":{"total":83738,"mean":8377.34,"min":8255,"max":8461,"stddev":55.3,"p50":8383,"p90":8463,"p99":8463},"exists simple":{"total":582187,"mean":58544,"min":54824,"max":59337,"stddev":1327.48,"p50":58847,"p90":59359,"p99":59359},"exists simple with path expression":{"total":214081,"mean":21398.23,"min":20623,"max":21999,"stddev":426.3,"p50":21439,"p90":21999,"p99":21999},"exists recursive (depth 3)":{"total":419516,"mean":41907.56,"min":40691,"max":42639,"stddev":692.67,"p50":42143,"p90":42655,"p99":42655},"assoc2join simple":{"total":521139,"mean":52094.23,"min":49418,"max":52906,"stddev":1052.29,"p50":52575,"p90":52927,"p99":52927},"assoc2join recursive (depth 3)":{"total":439593,"mean":44133.34,"min":42005,"max":44973,"stddev":916.22,"p50":44671,"p90":44991,"p99":44991}}},"f8035155":{"date":"2025-08-28T10:27:33.581Z","benchmarks":{"select simple":{"total":897960,"mean":89539.56,"min":86202,"max":91014,"stddev":1674.94,"p50":90303,"p90":91071,"p99":91071},"select wildcard":{"total":793244,"mean":79192.89,"min":77701,"max":80393,"stddev":920.78,"p50":79167,"p90":80447,"p99":80447},"select wildcard with calculated element":{"total":337316,"mean":33747.56,"min":33322,"max":34001,"stddev":188.68,"p50":33759,"p90":34015,"p99":34015},"expand simple":{"total":202536,"mean":20217.78,"min":19211,"max":20933,"stddev":682.36,"p50":20607,"p90":20943,"p99":20943},"expand recursive (depth 3)":{"total":83893,"mean":8388.89,"min":8249,"max":8440,"stddev":54.19,"p50":8407,"p90":8447,"p99":8447},"exists simple":{"total":587313,"mean":58629.34,"min":55979,"max":60074,"stddev":1334.15,"p50":58911,"p90":60095,"p99":60095},"exists simple with path expression":{"total":227865,"mean":22781.34,"min":22715,"max":22936,"stddev":62.2,"p50":22767,"p90":22943,"p99":22943},"exists recursive (depth 3)":{"total":421361,"mean":42106.67,"min":41163,"max":42981,"stddev":621.06,"p50":42207,"p90":43007,"p99":43007},"assoc2join simple":{"total":504886,"mean":50263.12,"min":37234,"max":52613,"stddev":4630.34,"p50":51775,"p90":52639,"p99":52639},"assoc2join recursive (depth 3)":{"total":424099,"mean":42743.12,"min":40717,"max":44305,"stddev":1257.29,"p50":43327,"p90":44319,"p99":44319}}},"e012aa8b":{"date":"2025-09-26T11:39:31.733Z","benchmarks":{"select simple":{"total":907544,"mean":90464,"min":85465,"max":93965,"stddev":2647.57,"p50":90303,"p90":94015,"p99":94015},"select wildcard":{"total":776069,"mean":77671.12,"min":72634,"max":79941,"stddev":2295.78,"p50":78719,"p90":79999,"p99":79999},"select wildcard with calculated element":{"total":345986,"mean":34604.45,"min":34470,"max":34744,"stddev":98.28,"p50":34623,"p90":34751,"p99":34751},"expand simple":{"total":211287,"mean":21119.12,"min":20927,"max":21237,"stddev":116.64,"p50":21167,"p90":21247,"p99":21247},"expand recursive (depth 3)":{"total":84288,"mean":8422.45,"min":8091,"max":8537,"stddev":147.15,"p50":8519,"p90":8543,"p99":8543},"exists simple":{"total":598327,"mean":59777.78,"min":58949,"max":60268,"stddev":330.54,"p50":59839,"p90":60287,"p99":60287},"exists simple with path expression":{"total":228583,"mean":22868.45,"min":21632,"max":23228,"stddev":498.77,"p50":23087,"p90":23231,"p99":23231},"exists recursive (depth 3)":{"total":420710,"mean":41882.67,"min":37279,"max":43789,"stddev":2170.35,"p50":42399,"p90":43807,"p99":43807},"assoc2join simple":{"total":517521,"mean":51745.78,"min":49613,"max":54187,"stddev":1422.08,"p50":52255,"p90":54207,"p99":54207},"assoc2join recursive (depth 3)":{"total":449974,"mean":44972.45,"min":44460,"max":45405,"stddev":323.35,"p50":45087,"p90":45407,"p99":45407},"@cds.search simple":{"total":501534,"mean":50128,"min":48999,"max":51078,"stddev":656.33,"p50":50367,"p90":51103,"p99":51103},"@cds.search deep":{"total":481465,"mean":48375.12,"min":47062,"max":49912,"stddev":957.49,"p50":48319,"p90":49919,"p99":49919}}},"1526a1fc":{"date":"2025-10-07T12:02:38.636Z","benchmarks":{"select simple":{"total":905569,"mean":90641.78,"min":89254,"max":91697,"stddev":679.85,"p50":90879,"p90":91711,"p99":91711},"select wildcard":{"total":755952,"mean":75182.23,"min":69261,"max":78456,"stddev":3031.11,"p50":76863,"p90":78463,"p99":78463},"select wildcard with calculated element":{"total":338754,"mean":33889.78,"min":33529,"max":34115,"stddev":166.7,"p50":33887,"p90":34143,"p99":34143},"expand simple":{"total":205719,"mean":20544.89,"min":19889,"max":20918,"stddev":374.87,"p50":20751,"p90":20927,"p99":20927},"expand recursive (depth 3)":{"total":83852,"mean":8385.34,"min":8319,"max":8454,"stddev":40.09,"p50":8407,"p90":8455,"p99":8455},"exists simple":{"total":596050,"mean":59621.34,"min":59305,"max":59853,"stddev":169.33,"p50":59647,"p90":59871,"p99":59871},"exists simple with path expression":{"total":229290,"mean":22925.34,"min":22733,"max":23213,"stddev":153.29,"p50":22943,"p90":23215,"p99":23215},"exists recursive (depth 3)":{"total":426874,"mean":42739.56,"min":40608,"max":43137,"stddev":756.43,"p50":43039,"p90":43167,"p99":43167},"assoc2join simple":{"total":536380,"mean":53601.78,"min":53367,"max":53776,"stddev":163.25,"p50":53695,"p90":53791,"p99":53791},"assoc2join recursive (depth 3)":{"total":449226,"mean":44926.23,"min":44793,"max":45047,"stddev":89.39,"p50":44927,"p90":45055,"p99":45055},"@cds.search simple":{"total":506190,"mean":50636.45,"min":49756,"max":50971,"stddev":346.12,"p50":50719,"p90":50975,"p99":50975},"@cds.search deep":{"total":502336,"mean":50209.78,"min":49729,"max":50612,"stddev":277.38,"p50":50271,"p90":50623,"p99":50623},"scoped query":{"total":0,"mean":0,"min":0,"max":0,"stddev":0,"p50":0,"p90":0,"p99":0}}}} diff --git a/db-service/bench/cqn4sql/results/perf-benchmarks.html b/db-service/bench/cqn4sql/results/perf-benchmarks.html new file mode 100644 index 000000000..a8c87f649 --- /dev/null +++ b/db-service/bench/cqn4sql/results/perf-benchmarks.html @@ -0,0 +1,96 @@ + + + + +CQN4SQL Benchmarks + + +

CQN4SQL Benchmarks

+
+ Data: cqn4sql-benchmarks.json • Commits: 13 +
+ Measurements in requests per second (higher is better) +
+ +
+ + + + + +
+ +
+ + + + \ No newline at end of file diff --git a/db-service/bench/cqn4sql/utils/format-benchmarks.js b/db-service/bench/cqn4sql/utils/format-benchmarks.js new file mode 100644 index 000000000..c7a16ffd3 --- /dev/null +++ b/db-service/bench/cqn4sql/utils/format-benchmarks.js @@ -0,0 +1,105 @@ +'use strict' + +const fs = require('fs') +const path = require('path') +const { execSync } = require('child_process') + +function getCommitShort() { + try { + return execSync('git rev-parse --short HEAD', { stdio: ['ignore', 'pipe', 'ignore'] }) + .toString() + .trim() + } catch { + const sha = process.env.GITHUB_SHA || process.env.CI_COMMIT_SHA || '' + return sha ? sha.slice(0, 7) : `unknown-${new Date().toISOString().replace(/[:.]/g, '-')}` + } +} + +function compactRequests(requests) { + return { + total: requests.total, + mean: requests.mean, + min: requests.min, + max: requests.max, + stddev: requests.stddev, + p50: requests.p50, + p90: requests.p90, + p99: requests.p99, + } +} + +function collectBenchmarksForFile(resultsPath, testFileBase) { + const lines = fs.existsSync(resultsPath) ? fs.readFileSync(resultsPath, 'utf8').split(/\r?\n/).filter(Boolean) : [] + + const benchmarks = {} + for (const line of lines) { + let obj + try { + obj = JSON.parse(line) + } catch { + continue + } + const key = Object.keys(obj)[0] + const data = obj[key] + if (!data) continue + + const fromThisFile = data.file === testFileBase || (typeof key === 'string' && key.startsWith(`${testFileBase}:`)) + if (!fromThisFile) continue + + const title = data.title || key.split(':')[1] || key + if (data.requests) benchmarks[title] = compactRequests(data.requests) // keep only subset of "requests" + } + return benchmarks +} + +/** + * Formats & writes the cumulative dump: + * dump[commit] = { date, benchmarks } + * + * @param {object} opts + * @param {string} opts.testFile absolute __filename of the calling test + * @param {string} [opts.resultsFile='results.bench'] + * @param {string} [opts.dumpFile='perf-benchmarks.json'] + * @returns {false | {commit:string,file:string,count:number}} + */ +function writeDump({ + testFile, + resultsFile = 'results.bench', + dumpFile = 'cqn4sql-benchmarks.json', + deleteResultsFile = true, +}) { + const testFileBase = path.basename(testFile) + const resultsPath = path.resolve(process.cwd(), resultsFile) + const dumpPath = path.resolve(process.cwd() + '/results', dumpFile) + + const benchmarks = collectBenchmarksForFile(resultsPath, testFileBase) + if (!Object.keys(benchmarks).length) return false + + const commit = getCommitShort() + const entry = { date: new Date().toISOString(), benchmarks } + + let dump = {} + if (fs.existsSync(dumpPath)) { + try { + dump = JSON.parse(fs.readFileSync(dumpPath, 'utf8')) || {} + } catch { + dump = {} + } + } + dump[commit] = entry + + fs.mkdirSync(path.dirname(dumpPath), { recursive: true }) + fs.writeFileSync(dumpPath, JSON.stringify(dump) + '\n', 'utf8') + + if (deleteResultsFile && fs.existsSync(resultsPath)) { + try { + fs.unlinkSync(resultsPath) + } catch { + /* ignore */ + } + } + + return { commit, file: dumpPath, count: Object.keys(benchmarks).length } +} + +module.exports = { writeDump } diff --git a/db-service/bench/cqn4sql/utils/visualize-benchmarks.js b/db-service/bench/cqn4sql/utils/visualize-benchmarks.js new file mode 100644 index 000000000..a4600455a --- /dev/null +++ b/db-service/bench/cqn4sql/utils/visualize-benchmarks.js @@ -0,0 +1,171 @@ +#!/usr/bin/env node +'use strict' + +const fs = require('fs') +const path = require('path') + +const dumpPath = process.argv[2] || 'results/cqn4sql-benchmarks.json' +const outPath = process.argv[3] || 'dist/index.html' + +if (!fs.existsSync(dumpPath)) { + // eslint-disable-next-line no-console + console.error(`❌ Cannot find ${dumpPath}`) + process.exit(1) +} + +const dump = JSON.parse(fs.readFileSync(dumpPath, 'utf8')) + +// normalize + sort by date +const entries = Object.entries(dump) + .map(([commit, v]) => ({ commit, dateISO: v.date, date: new Date(v.date), benchmarks: v.benchmarks || {} })) + .sort((a, b) => a.date - b.date) + +const commits = entries.map(e => e.commit) +const commitDates = entries.map(e => e.dateISO) +const commitLabels = commits.map((sha, i) => { + const d = new Date(commitDates[i]) + const y = d.getUTCFullYear() + const m = String(d.getUTCMonth() + 1).padStart(2, '0') + const day = String(d.getUTCDate()).padStart(2, '0') + return `${sha} (${y}-${m}-${day})` +}) + + +// collect benchmark names +const benchNames = Array.from( + entries.reduce((s, e) => { + Object.keys(e.benchmarks).forEach(k => s.add(k)) + return s + }, new Set()) +).sort() + +// collect available metric keys (union across all benches/commits) +const metricSet = new Set() +for (const e of entries) { + for (const name of Object.keys(e.benchmarks)) { + const obj = e.benchmarks[name] + Object.keys(obj || {}).forEach(k => metricSet.add(k)) + } +} + +const metrics = ['mean', 'stddev', 'total', 'p50', 'p90', 'p99', 'min', 'max'] +const initialMetric = 'mean' + +// precompute all series data per metric to keep UI snappy +function buildSeriesForMetric(metric) { + return benchNames.map(name => { + const y = entries.map(e => { + const obj = e.benchmarks[name] + if (!obj) return null + const v = obj[metric] + return (typeof v === 'number') ? v : (v != null ? Number(v) : null) + }) + return { name, x: commits, y } + }) +} + +const allSeries = {} +for (const m of metrics) allSeries[m] = buildSeriesForMetric(m) + +// HTML (commit categories on X, metric selector, benchmark filter) +const html = ` + + + +CQN4SQL Benchmarks + + +

CQN4SQL Benchmarks

+
+ Data: ${path.basename(dumpPath)} • Commits: ${entries.length} +
+ Measurements in requests per second (higher is better) +
+ +
+ + + + + +
+ +
+ + + +` + +fs.mkdirSync(path.dirname(outPath), { recursive: true }) +fs.writeFileSync(outPath, html, 'utf8') +// eslint-disable-next-line no-console +console.log(`✅ wrote ${outPath} — metrics: [${metrics.join(', ')}], benches: ${benchNames.length}, commits: ${entries.length}`) diff --git a/db-service/bench/results.bench b/db-service/bench/results.bench new file mode 100644 index 000000000..8fdb6342c --- /dev/null +++ b/db-service/bench/results.bench @@ -0,0 +1,13 @@ +{"cqn4sql/performance-benchmarks.test.js:select simple":{"title":"select simple","connections":3,"duration":10.00110725,"samples":10,"start":"+016149-11-17T17:59:03.291Z","finish":"2025-10-07T11:14:51.845Z","errors":0,"timeouts":0,"mismatches":0,"non2xx":0,"resets":0,"1xx":0,"2xx":850273,"3xx":0,"4xx":0,"5xx":0,"statusCodeStats":{"200":{"count":850273}},"latency":{"average":0.01,"mean":0.01,"stddev":0.02,"min":1,"max":5,"p0_001":0,"p0_01":0,"p0_1":0,"p1":0,"p2_5":0,"p10":0,"p25":0,"p50":0,"p75":0,"p90":0,"p97_5":0,"p99":0,"p99_9":0,"p99_99":0,"p99_999":2,"totalCount":850273},"requests":{"average":85180.45,"mean":85180.45,"stddev":4449.74,"min":73120,"max":88374,"total":850273,"p0_001":73151,"p0_01":73151,"p0_1":73151,"p1":73151,"p2_5":73151,"p10":73151,"p25":84799,"p50":86527,"p75":87359,"p90":88383,"p97_5":88383,"p99":88383,"p99_9":88383,"p99_99":88383,"p99_999":88383,"sent":850273},"throughput":{"average":0,"mean":0,"stddev":0,"min":0,"max":0,"total":0,"p0_001":0,"p0_01":0,"p0_1":0,"p1":0,"p2_5":0,"p10":0,"p25":0,"p50":0,"p75":0,"p90":0,"p97_5":0,"p99":0,"p99_9":0,"p99_99":0,"p99_999":0},"file":"cqn4sql/performance-benchmarks.test.js","line":"13:42"}} +{"cqn4sql/performance-benchmarks.test.js:select wildcard":{"title":"select wildcard","connections":3,"duration":10.000926584,"samples":10,"start":"+016150-04-17T12:31:15.416Z","finish":"2025-10-07T11:15:04.871Z","errors":0,"timeouts":0,"mismatches":0,"non2xx":0,"resets":0,"1xx":0,"2xx":742762,"3xx":0,"4xx":0,"5xx":0,"statusCodeStats":{"200":{"count":742762}},"latency":{"average":0.01,"mean":0.01,"stddev":0.01,"min":1,"max":2,"p0_001":0,"p0_01":0,"p0_1":0,"p1":0,"p2_5":0,"p10":0,"p25":0,"p50":0,"p75":0,"p90":0,"p97_5":0,"p99":0,"p99_9":0,"p99_99":0,"p99_999":1,"totalCount":742762},"requests":{"average":74208,"mean":74208,"stddev":2019.81,"min":68841,"max":76092,"total":742762,"p0_001":68863,"p0_01":68863,"p0_1":68863,"p1":68863,"p2_5":68863,"p10":68863,"p25":73983,"p50":74879,"p75":75071,"p90":76095,"p97_5":76095,"p99":76095,"p99_9":76095,"p99_99":76095,"p99_999":76095,"sent":742762},"throughput":{"average":0,"mean":0,"stddev":0,"min":0,"max":0,"total":0,"p0_001":0,"p0_01":0,"p0_1":0,"p1":0,"p2_5":0,"p10":0,"p25":0,"p50":0,"p75":0,"p90":0,"p97_5":0,"p99":0,"p99_9":0,"p99_99":0,"p99_999":0},"file":"cqn4sql/performance-benchmarks.test.js","line":"13:42"}} +{"cqn4sql/performance-benchmarks.test.js:select wildcard with calculated element":{"title":"select wildcard with calculated element","connections":3,"duration":10.0010655,"samples":10,"start":"+016150-09-15T07:02:41.208Z","finish":"2025-10-07T11:15:17.898Z","errors":0,"timeouts":0,"mismatches":0,"non2xx":0,"resets":0,"1xx":0,"2xx":312764,"3xx":0,"4xx":0,"5xx":0,"statusCodeStats":{"200":{"count":312764}},"latency":{"average":0.01,"mean":0.01,"stddev":0.02,"min":1,"max":5,"p0_001":0,"p0_01":0,"p0_1":0,"p1":0,"p2_5":0,"p10":0,"p25":0,"p50":0,"p75":0,"p90":0,"p97_5":0,"p99":0,"p99_9":0,"p99_99":1,"p99_999":2,"totalCount":312764},"requests":{"average":31208,"mean":31208,"stddev":1336.19,"min":27928,"max":32252,"total":312764,"p0_001":27935,"p0_01":27935,"p0_1":27935,"p1":27935,"p2_5":27935,"p10":27935,"p25":31535,"p50":31855,"p75":31951,"p90":32255,"p97_5":32255,"p99":32255,"p99_9":32255,"p99_99":32255,"p99_999":32255,"sent":312764},"throughput":{"average":0,"mean":0,"stddev":0,"min":0,"max":0,"total":0,"p0_001":0,"p0_01":0,"p0_1":0,"p1":0,"p2_5":0,"p10":0,"p25":0,"p50":0,"p75":0,"p90":0,"p97_5":0,"p99":0,"p99_9":0,"p99_99":0,"p99_999":0},"file":"cqn4sql/performance-benchmarks.test.js","line":"13:42"}} +{"cqn4sql/performance-benchmarks.test.js:expand simple":{"title":"expand simple","connections":3,"duration":10.000898542,"samples":10,"start":"+016151-02-13T00:22:29.458Z","finish":"2025-10-07T11:15:30.919Z","errors":0,"timeouts":0,"mismatches":0,"non2xx":0,"resets":0,"1xx":0,"2xx":195206,"3xx":0,"4xx":0,"5xx":0,"statusCodeStats":{"200":{"count":195206}},"latency":{"average":0.01,"mean":0.01,"stddev":0.03,"min":1,"max":3,"p0_001":0,"p0_01":0,"p0_1":0,"p1":0,"p2_5":0,"p10":0,"p25":0,"p50":0,"p75":0,"p90":0,"p97_5":0,"p99":0,"p99_9":0,"p99_99":2,"p99_999":2,"totalCount":195206},"requests":{"average":19501.34,"mean":19501.34,"stddev":478.1,"min":18292,"max":19943,"total":195206,"p0_001":18303,"p0_01":18303,"p0_1":18303,"p1":18303,"p2_5":18303,"p10":18303,"p25":19391,"p50":19679,"p75":19807,"p90":19951,"p97_5":19951,"p99":19951,"p99_9":19951,"p99_99":19951,"p99_999":19951,"sent":195206},"throughput":{"average":0,"mean":0,"stddev":0,"min":0,"max":0,"total":0,"p0_001":0,"p0_01":0,"p0_1":0,"p1":0,"p2_5":0,"p10":0,"p25":0,"p50":0,"p75":0,"p90":0,"p97_5":0,"p99":0,"p99_9":0,"p99_99":0,"p99_999":0},"file":"cqn4sql/performance-benchmarks.test.js","line":"13:42"}} +{"cqn4sql/performance-benchmarks.test.js:expand recursive (depth 3)":{"title":"expand recursive (depth 3)","connections":3,"duration":10.000859209,"samples":10,"start":"+016151-07-13T17:57:40.666Z","finish":"2025-10-07T11:15:43.942Z","errors":0,"timeouts":0,"mismatches":0,"non2xx":0,"resets":0,"1xx":0,"2xx":78747,"3xx":0,"4xx":0,"5xx":0,"statusCodeStats":{"200":{"count":78747}},"latency":{"average":0.01,"mean":0.01,"stddev":0.05,"min":1,"max":2,"p0_001":0,"p0_01":0,"p0_1":0,"p1":0,"p2_5":0,"p10":0,"p25":0,"p50":0,"p75":0,"p90":0,"p97_5":0,"p99":0,"p99_9":1,"p99_99":2,"p99_999":2,"totalCount":78747},"requests":{"average":7921.12,"mean":7921.12,"stddev":56.79,"min":7842,"max":8039,"total":78747,"p0_001":7843,"p0_01":7843,"p0_1":7843,"p1":7843,"p2_5":7843,"p10":7843,"p25":7883,"p50":7907,"p75":7951,"p90":8039,"p97_5":8039,"p99":8039,"p99_9":8039,"p99_99":8039,"p99_999":8039,"sent":78747},"throughput":{"average":0,"mean":0,"stddev":0,"min":0,"max":0,"total":0,"p0_001":0,"p0_01":0,"p0_1":0,"p1":0,"p2_5":0,"p10":0,"p25":0,"p50":0,"p75":0,"p90":0,"p97_5":0,"p99":0,"p99_9":0,"p99_99":0,"p99_999":0},"file":"cqn4sql/performance-benchmarks.test.js","line":"13:42"}} +{"cqn4sql/performance-benchmarks.test.js:exists simple":{"title":"exists simple","connections":3,"duration":10.000950875,"samples":10,"start":"+016151-12-11T11:11:06.000Z","finish":"2025-10-07T11:15:56.963Z","errors":0,"timeouts":0,"mismatches":0,"non2xx":0,"resets":0,"1xx":0,"2xx":564866,"3xx":0,"4xx":0,"5xx":0,"statusCodeStats":{"200":{"count":564866}},"latency":{"average":0.01,"mean":0.01,"stddev":0.01,"min":1,"max":2,"p0_001":0,"p0_01":0,"p0_1":0,"p1":0,"p2_5":0,"p10":0,"p25":0,"p50":0,"p75":0,"p90":0,"p97_5":0,"p99":0,"p99_9":0,"p99_99":0,"p99_999":1,"totalCount":564866},"requests":{"average":56492.45,"mean":56492.45,"stddev":367.79,"min":55791,"max":57040,"total":564866,"p0_001":55807,"p0_01":55807,"p0_1":55807,"p1":55807,"p2_5":55807,"p10":55807,"p25":56319,"p50":56543,"p75":56767,"p90":57055,"p97_5":57055,"p99":57055,"p99_9":57055,"p99_99":57055,"p99_999":57055,"sent":564866},"throughput":{"average":0,"mean":0,"stddev":0,"min":0,"max":0,"total":0,"p0_001":0,"p0_01":0,"p0_1":0,"p1":0,"p2_5":0,"p10":0,"p25":0,"p50":0,"p75":0,"p90":0,"p97_5":0,"p99":0,"p99_9":0,"p99_99":0,"p99_999":0},"file":"cqn4sql/performance-benchmarks.test.js","line":"13:42"}} +{"cqn4sql/performance-benchmarks.test.js:exists simple with path expression":{"title":"exists simple with path expression","connections":3,"duration":10.000938709,"samples":10,"start":"+016152-05-10T04:36:13.916Z","finish":"2025-10-07T11:16:09.985Z","errors":0,"timeouts":0,"mismatches":0,"non2xx":0,"resets":0,"1xx":0,"2xx":215359,"3xx":0,"4xx":0,"5xx":0,"statusCodeStats":{"200":{"count":215359}},"latency":{"average":0.01,"mean":0.01,"stddev":0.03,"min":1,"max":3,"p0_001":0,"p0_01":0,"p0_1":0,"p1":0,"p2_5":0,"p10":0,"p25":0,"p50":0,"p75":0,"p90":0,"p97_5":0,"p99":0,"p99_9":0,"p99_99":1,"p99_999":3,"totalCount":215359},"requests":{"average":21515.56,"mean":21515.56,"stddev":366.4,"min":20814,"max":21855,"total":215359,"p0_001":20815,"p0_01":20815,"p0_1":20815,"p1":20815,"p2_5":20815,"p10":20815,"p25":21487,"p50":21711,"p75":21759,"p90":21855,"p97_5":21855,"p99":21855,"p99_9":21855,"p99_99":21855,"p99_999":21855,"sent":215359},"throughput":{"average":0,"mean":0,"stddev":0,"min":0,"max":0,"total":0,"p0_001":0,"p0_01":0,"p0_1":0,"p1":0,"p2_5":0,"p10":0,"p25":0,"p50":0,"p75":0,"p90":0,"p97_5":0,"p99":0,"p99_9":0,"p99_99":0,"p99_999":0},"file":"cqn4sql/performance-benchmarks.test.js","line":"13:42"}} +{"cqn4sql/performance-benchmarks.test.js:exists recursive (depth 3)":{"title":"exists recursive (depth 3)","connections":3,"duration":10.001187084,"samples":10,"start":"+016152-10-07T22:09:17.041Z","finish":"2025-10-07T11:16:23.008Z","errors":0,"timeouts":0,"mismatches":0,"non2xx":0,"resets":0,"1xx":0,"2xx":408113,"3xx":0,"4xx":0,"5xx":0,"statusCodeStats":{"200":{"count":408113}},"latency":{"average":0.01,"mean":0.01,"stddev":0.03,"min":1,"max":2,"p0_001":0,"p0_01":0,"p0_1":0,"p1":0,"p2_5":0,"p10":0,"p25":0,"p50":0,"p75":0,"p90":0,"p97_5":0,"p99":0,"p99_9":0,"p99_99":1,"p99_999":2,"totalCount":408113},"requests":{"average":40869.34,"mean":40869.34,"stddev":493.45,"min":40345,"max":41994,"total":408113,"p0_001":40351,"p0_01":40351,"p0_1":40351,"p1":40351,"p2_5":40351,"p10":40351,"p25":40575,"p50":40735,"p75":40991,"p90":42015,"p97_5":42015,"p99":42015,"p99_9":42015,"p99_99":42015,"p99_999":42015,"sent":408113},"throughput":{"average":0,"mean":0,"stddev":0,"min":0,"max":0,"total":0,"p0_001":0,"p0_01":0,"p0_1":0,"p1":0,"p2_5":0,"p10":0,"p25":0,"p50":0,"p75":0,"p90":0,"p97_5":0,"p99":0,"p99_9":0,"p99_99":0,"p99_999":0},"file":"cqn4sql/performance-benchmarks.test.js","line":"13:42"}} +{"cqn4sql/performance-benchmarks.test.js:assoc2join simple":{"title":"assoc2join simple","connections":3,"duration":10.000882209,"samples":10,"start":"+016153-03-07T15:44:32.166Z","finish":"2025-10-07T11:16:36.031Z","errors":0,"timeouts":0,"mismatches":0,"non2xx":0,"resets":0,"1xx":0,"2xx":490901,"3xx":0,"4xx":0,"5xx":0,"statusCodeStats":{"200":{"count":490901}},"latency":{"average":0.01,"mean":0.01,"stddev":0.02,"min":1,"max":5,"p0_001":0,"p0_01":0,"p0_1":0,"p1":0,"p2_5":0,"p10":0,"p25":0,"p50":0,"p75":0,"p90":0,"p97_5":0,"p99":0,"p99_9":0,"p99_99":1,"p99_999":2,"totalCount":490901},"requests":{"average":48976,"mean":48976,"stddev":3202.14,"min":42950,"max":51778,"total":490901,"p0_001":42975,"p0_01":42975,"p0_1":42975,"p1":42975,"p2_5":42975,"p10":42975,"p25":49087,"p50":50239,"p75":51359,"p90":51807,"p97_5":51807,"p99":51807,"p99_9":51807,"p99_99":51807,"p99_999":51807,"sent":490901},"throughput":{"average":0,"mean":0,"stddev":0,"min":0,"max":0,"total":0,"p0_001":0,"p0_01":0,"p0_1":0,"p1":0,"p2_5":0,"p10":0,"p25":0,"p50":0,"p75":0,"p90":0,"p97_5":0,"p99":0,"p99_9":0,"p99_99":0,"p99_999":0},"file":"cqn4sql/performance-benchmarks.test.js","line":"13:42"}} +{"cqn4sql/performance-benchmarks.test.js:assoc2join recursive (depth 3)":{"title":"assoc2join recursive (depth 3)","connections":3,"duration":10.000888542,"samples":10,"start":"+016153-08-05T09:40:38.791Z","finish":"2025-10-07T11:16:49.055Z","errors":0,"timeouts":0,"mismatches":0,"non2xx":0,"resets":0,"1xx":0,"2xx":423886,"3xx":0,"4xx":0,"5xx":0,"statusCodeStats":{"200":{"count":423886}},"latency":{"average":0.01,"mean":0.01,"stddev":0.02,"min":1,"max":4,"p0_001":0,"p0_01":0,"p0_1":0,"p1":0,"p2_5":0,"p10":0,"p25":0,"p50":0,"p75":0,"p90":0,"p97_5":0,"p99":0,"p99_9":0,"p99_99":0,"p99_999":2,"totalCount":423886},"requests":{"average":42362.67,"mean":42362.67,"stddev":320.72,"min":41678,"max":42731,"total":423886,"p0_001":41695,"p0_01":41695,"p0_1":41695,"p1":41695,"p2_5":41695,"p10":41695,"p25":42335,"p50":42431,"p75":42623,"p90":42751,"p97_5":42751,"p99":42751,"p99_9":42751,"p99_99":42751,"p99_999":42751,"sent":423886},"throughput":{"average":0,"mean":0,"stddev":0,"min":0,"max":0,"total":0,"p0_001":0,"p0_01":0,"p0_1":0,"p1":0,"p2_5":0,"p10":0,"p25":0,"p50":0,"p75":0,"p90":0,"p97_5":0,"p99":0,"p99_9":0,"p99_99":0,"p99_999":0},"file":"cqn4sql/performance-benchmarks.test.js","line":"13:42"}} +{"cqn4sql/performance-benchmarks.test.js:@cds.search simple":{"title":"@cds.search simple","connections":3,"duration":10.001105625,"samples":10,"start":"+016154-01-03T03:43:23.583Z","finish":"2025-10-07T11:17:02.079Z","errors":0,"timeouts":0,"mismatches":0,"non2xx":0,"resets":0,"1xx":0,"2xx":474480,"3xx":0,"4xx":0,"5xx":0,"statusCodeStats":{"200":{"count":474480}},"latency":{"average":0.01,"mean":0.01,"stddev":0.02,"min":1,"max":5,"p0_001":0,"p0_01":0,"p0_1":0,"p1":0,"p2_5":0,"p10":0,"p25":0,"p50":0,"p75":0,"p90":0,"p97_5":0,"p99":0,"p99_9":0,"p99_99":1,"p99_999":2,"totalCount":474480},"requests":{"average":47379.56,"mean":47379.56,"stddev":1039.27,"min":45719,"max":49224,"total":474480,"p0_001":45727,"p0_01":45727,"p0_1":45727,"p1":45727,"p2_5":45727,"p10":45727,"p25":46623,"p50":47455,"p75":48031,"p90":49247,"p97_5":49247,"p99":49247,"p99_9":49247,"p99_99":49247,"p99_999":49247,"sent":474480},"throughput":{"average":0,"mean":0,"stddev":0,"min":0,"max":0,"total":0,"p0_001":0,"p0_01":0,"p0_1":0,"p1":0,"p2_5":0,"p10":0,"p25":0,"p50":0,"p75":0,"p90":0,"p97_5":0,"p99":0,"p99_9":0,"p99_99":0,"p99_999":0},"file":"cqn4sql/performance-benchmarks.test.js","line":"13:42"}} +{"cqn4sql/performance-benchmarks.test.js:@cds.search deep":{"title":"@cds.search deep","connections":3,"duration":10.000951292,"samples":10,"start":"+016154-06-02T22:02:42.916Z","finish":"2025-10-07T11:17:15.104Z","errors":0,"timeouts":0,"mismatches":0,"non2xx":0,"resets":0,"1xx":0,"2xx":477881,"3xx":0,"4xx":0,"5xx":0,"statusCodeStats":{"200":{"count":477881}},"latency":{"average":0.01,"mean":0.01,"stddev":0.02,"min":1,"max":2,"p0_001":0,"p0_01":0,"p0_1":0,"p1":0,"p2_5":0,"p10":0,"p25":0,"p50":0,"p75":0,"p90":0,"p97_5":0,"p99":0,"p99_9":0,"p99_99":0,"p99_999":1,"totalCount":477881},"requests":{"average":47895.12,"mean":47895.12,"stddev":502.53,"min":46969,"max":48508,"total":477881,"p0_001":46975,"p0_01":46975,"p0_1":46975,"p1":46975,"p2_5":46975,"p10":46975,"p25":47519,"p50":48031,"p75":48287,"p90":48511,"p97_5":48511,"p99":48511,"p99_9":48511,"p99_99":48511,"p99_999":48511,"sent":477881},"throughput":{"average":0,"mean":0,"stddev":0,"min":0,"max":0,"total":0,"p0_001":0,"p0_01":0,"p0_1":0,"p1":0,"p2_5":0,"p10":0,"p25":0,"p50":0,"p75":0,"p90":0,"p97_5":0,"p99":0,"p99_9":0,"p99_99":0,"p99_999":0},"file":"cqn4sql/performance-benchmarks.test.js","line":"13:42"}} +{"cqn4sql/performance-benchmarks.test.js:scoped query":{"title":"scoped query","connections":3,"duration":10.000821583,"samples":10,"start":"+016154-10-31T17:16:37.375Z","finish":"2025-10-07T11:17:28.133Z","errors":701086,"timeouts":0,"mismatches":0,"non2xx":"0[object Object]","resets":0,"1xx":0,"2xx":0,"3xx":0,"4xx":0,"5xx":701086,"statusCodeStats":{"500":{"count":701086}},"latency":{"average":0,"mean":0,"stddev":0,"min":0,"max":0,"p0_001":0,"p0_01":0,"p0_1":0,"p1":0,"p2_5":0,"p10":0,"p25":0,"p50":0,"p75":0,"p90":0,"p97_5":0,"p99":0,"p99_9":0,"p99_99":0,"p99_999":0,"totalCount":0},"requests":{"average":0,"mean":0,"stddev":0,"min":0,"max":0,"total":0,"p0_001":0,"p0_01":0,"p0_1":0,"p1":0,"p2_5":0,"p10":0,"p25":0,"p50":0,"p75":0,"p90":0,"p97_5":0,"p99":0,"p99_9":0,"p99_99":0,"p99_999":0,"sent":701086},"throughput":{"average":0,"mean":0,"stddev":0,"min":0,"max":0,"total":0,"p0_001":0,"p0_01":0,"p0_1":0,"p1":0,"p2_5":0,"p10":0,"p25":0,"p50":0,"p75":0,"p90":0,"p97_5":0,"p99":0,"p99_9":0,"p99_99":0,"p99_999":0},"file":"cqn4sql/performance-benchmarks.test.js","line":"13:42"}}