pure-orm 4.0.3 → 4.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.benchmarks/bench-core-baseline.json +303 -0
- package/README.md +0 -7
- package/babel.config.js +4 -1
- package/coverage/clover.xml +1492 -1231
- package/coverage/coverage-final.json +103 -103
- package/coverage/lcov-report/dist/src/core.js.html +590 -383
- package/coverage/lcov-report/dist/src/driver-integrations/index.html +20 -20
- package/coverage/lcov-report/dist/src/driver-integrations/pgp.js.html +52 -52
- package/coverage/lcov-report/dist/src/index.html +28 -28
- package/coverage/lcov-report/dist/src/index.js.html +2 -2
- package/coverage/lcov-report/dist/src/orm.js.html +392 -209
- package/coverage/lcov-report/dist/test-utils/blog/entities.js.html +1 -1
- package/coverage/lcov-report/dist/test-utils/blog/index.html +1 -1
- package/coverage/lcov-report/dist/test-utils/blog/models/article.js.html +15 -15
- package/coverage/lcov-report/dist/test-utils/blog/models/article_tag.js.html +2 -2
- package/coverage/lcov-report/dist/test-utils/blog/models/index.html +1 -1
- package/coverage/lcov-report/dist/test-utils/blog/models/person.js.html +13 -13
- package/coverage/lcov-report/dist/test-utils/blog/models/tag.js.html +1 -1
- package/coverage/lcov-report/dist/test-utils/five/entities.js.html +1 -1
- package/coverage/lcov-report/dist/test-utils/five/index.html +1 -1
- package/coverage/lcov-report/dist/test-utils/five/models/index.html +1 -1
- package/coverage/lcov-report/dist/test-utils/five/models/line-item.js.html +4 -4
- package/coverage/lcov-report/dist/test-utils/five/models/order.js.html +3 -3
- package/coverage/lcov-report/dist/test-utils/five/models/parcel-event.js.html +6 -6
- package/coverage/lcov-report/dist/test-utils/five/models/parcel-line-item.js.html +7 -7
- package/coverage/lcov-report/dist/test-utils/five/models/parcel.js.html +2 -2
- package/coverage/lcov-report/dist/test-utils/fourteen/entities.js.html +1 -1
- package/coverage/lcov-report/dist/test-utils/fourteen/index.html +1 -1
- package/coverage/lcov-report/dist/test-utils/fourteen/models/customer.js.html +1 -1
- package/coverage/lcov-report/dist/test-utils/fourteen/models/index.html +1 -1
- package/coverage/lcov-report/dist/test-utils/fourteen/models/person.js.html +1 -1
- package/coverage/lcov-report/dist/test-utils/nine/entities.js.html +1 -1
- package/coverage/lcov-report/dist/test-utils/nine/index.html +1 -1
- package/coverage/lcov-report/dist/test-utils/nine/models/feature-switch.js.html +6 -6
- package/coverage/lcov-report/dist/test-utils/nine/models/index.html +1 -1
- package/coverage/lcov-report/dist/test-utils/order/entities.js.html +9 -9
- package/coverage/lcov-report/dist/test-utils/order/index.html +1 -1
- package/coverage/lcov-report/dist/test-utils/order/models/index.html +14 -14
- package/coverage/lcov-report/dist/test-utils/order/models/line-item.js.html +11 -11
- package/coverage/lcov-report/dist/test-utils/order/models/order.js.html +41 -41
- package/coverage/lcov-report/dist/test-utils/order/models/product-variant.js.html +18 -18
- package/coverage/lcov-report/dist/test-utils/order/models/product.js.html +17 -17
- package/coverage/lcov-report/dist/test-utils/order/models/utm-source.js.html +12 -12
- package/coverage/lcov-report/dist/test-utils/order-more/entities.js.html +1 -1
- package/coverage/lcov-report/dist/test-utils/order-more/index.html +1 -1
- package/coverage/lcov-report/dist/test-utils/order-more/models/actual-product-variant.js.html +3 -3
- package/coverage/lcov-report/dist/test-utils/order-more/models/color.js.html +6 -6
- package/coverage/lcov-report/dist/test-utils/order-more/models/customer.js.html +3 -3
- package/coverage/lcov-report/dist/test-utils/order-more/models/gender.js.html +4 -4
- package/coverage/lcov-report/dist/test-utils/order-more/models/index.html +23 -23
- package/coverage/lcov-report/dist/test-utils/order-more/models/inventory-level.js.html +11 -11
- package/coverage/lcov-report/dist/test-utils/order-more/models/line-item.js.html +15 -15
- package/coverage/lcov-report/dist/test-utils/order-more/models/order.js.html +39 -39
- package/coverage/lcov-report/dist/test-utils/order-more/models/parcel-event.js.html +6 -6
- package/coverage/lcov-report/dist/test-utils/order-more/models/parcel-line-item.js.html +7 -7
- package/coverage/lcov-report/dist/test-utils/order-more/models/parcel.js.html +2 -2
- package/coverage/lcov-report/dist/test-utils/order-more/models/physical-address.js.html +12 -12
- package/coverage/lcov-report/dist/test-utils/order-more/models/product-variant-image.js.html +7 -7
- package/coverage/lcov-report/dist/test-utils/order-more/models/product-variant.js.html +22 -22
- package/coverage/lcov-report/dist/test-utils/order-more/models/product.js.html +11 -11
- package/coverage/lcov-report/dist/test-utils/order-more/models/refund.js.html +11 -11
- package/coverage/lcov-report/dist/test-utils/order-more/models/shipment-actual-product-variant.js.html +9 -9
- package/coverage/lcov-report/dist/test-utils/order-more/models/shipment.js.html +4 -4
- package/coverage/lcov-report/dist/test-utils/order-more/models/size.js.html +4 -4
- package/coverage/lcov-report/dist/test-utils/order-more/models/utm-medium.js.html +15 -15
- package/coverage/lcov-report/dist/test-utils/order-more/models/utm-source.js.html +17 -17
- package/coverage/lcov-report/dist/test-utils/six/entities.js.html +1 -1
- package/coverage/lcov-report/dist/test-utils/six/index.html +1 -1
- package/coverage/lcov-report/dist/test-utils/six/models/customer.js.html +3 -3
- package/coverage/lcov-report/dist/test-utils/six/models/index.html +21 -21
- package/coverage/lcov-report/dist/test-utils/six/models/line-item.js.html +10 -10
- package/coverage/lcov-report/dist/test-utils/six/models/order.js.html +13 -13
- package/coverage/lcov-report/dist/test-utils/six/models/parcel-line-item.js.html +2 -2
- package/coverage/lcov-report/dist/test-utils/six/models/parcel.js.html +2 -2
- package/coverage/lcov-report/dist/test-utils/thirteen/entities.js.html +1 -1
- package/coverage/lcov-report/dist/test-utils/thirteen/index.html +1 -1
- package/coverage/lcov-report/dist/test-utils/thirteen/models/audience.js.html +2 -2
- package/coverage/lcov-report/dist/test-utils/thirteen/models/brand.js.html +2 -2
- package/coverage/lcov-report/dist/test-utils/thirteen/models/category.js.html +1 -1
- package/coverage/lcov-report/dist/test-utils/thirteen/models/index.html +14 -14
- package/coverage/lcov-report/dist/test-utils/thirteen/models/member.js.html +2 -2
- package/coverage/lcov-report/dist/test-utils/thirteen/models/passion.js.html +2 -2
- package/coverage/lcov-report/dist/test-utils/thirteen/models/product.js.html +10 -10
- package/coverage/lcov-report/dist/test-utils/thirteen/models/recommendation-audience.js.html +2 -2
- package/coverage/lcov-report/dist/test-utils/thirteen/models/recommendation.js.html +2 -2
- package/coverage/lcov-report/dist/test-utils/three/index.html +1 -1
- package/coverage/lcov-report/dist/test-utils/three/results.js.html +1 -1
- package/coverage/lcov-report/dist/test-utils/twelve/entities.js.html +1 -1
- package/coverage/lcov-report/dist/test-utils/twelve/index.html +1 -1
- package/coverage/lcov-report/dist/test-utils/twelve/models/index.html +1 -1
- package/coverage/lcov-report/dist/test-utils/twelve/models/member.js.html +1 -1
- package/coverage/lcov-report/dist/test-utils/twelve/models/prompt.js.html +2 -2
- package/coverage/lcov-report/dist/test-utils/two/index.html +1 -1
- package/coverage/lcov-report/dist/test-utils/two/results.js.html +1 -1
- package/coverage/lcov-report/index.html +103 -103
- package/coverage/lcov-report/src/core.ts.html +841 -415
- package/coverage/lcov-report/src/driver-integrations/index.html +20 -20
- package/coverage/lcov-report/src/driver-integrations/pgp.ts.html +58 -58
- package/coverage/lcov-report/src/index.html +28 -28
- package/coverage/lcov-report/src/index.ts.html +1 -1
- package/coverage/lcov-report/src/orm.ts.html +361 -298
- package/coverage/lcov-report/test-utils/blog/entities.ts.html +1 -1
- package/coverage/lcov-report/test-utils/blog/index.html +1 -1
- package/coverage/lcov-report/test-utils/blog/models/article.ts.html +15 -15
- package/coverage/lcov-report/test-utils/blog/models/article_tag.ts.html +2 -2
- package/coverage/lcov-report/test-utils/blog/models/index.html +1 -1
- package/coverage/lcov-report/test-utils/blog/models/person.ts.html +13 -13
- package/coverage/lcov-report/test-utils/blog/models/tag.ts.html +1 -1
- package/coverage/lcov-report/test-utils/five/entities.ts.html +1 -1
- package/coverage/lcov-report/test-utils/five/index.html +1 -1
- package/coverage/lcov-report/test-utils/five/models/index.html +1 -1
- package/coverage/lcov-report/test-utils/five/models/line-item.ts.html +4 -4
- package/coverage/lcov-report/test-utils/five/models/order.ts.html +3 -3
- package/coverage/lcov-report/test-utils/five/models/parcel-event.ts.html +6 -6
- package/coverage/lcov-report/test-utils/five/models/parcel-line-item.ts.html +7 -7
- package/coverage/lcov-report/test-utils/five/models/parcel.ts.html +2 -2
- package/coverage/lcov-report/test-utils/fourteen/entities.ts.html +1 -1
- package/coverage/lcov-report/test-utils/fourteen/index.html +1 -1
- package/coverage/lcov-report/test-utils/fourteen/models/customer.ts.html +1 -1
- package/coverage/lcov-report/test-utils/fourteen/models/index.html +1 -1
- package/coverage/lcov-report/test-utils/fourteen/models/person.ts.html +1 -1
- package/coverage/lcov-report/test-utils/nine/entities.ts.html +1 -1
- package/coverage/lcov-report/test-utils/nine/index.html +1 -1
- package/coverage/lcov-report/test-utils/nine/models/feature-switch.ts.html +8 -8
- package/coverage/lcov-report/test-utils/nine/models/index.html +1 -1
- package/coverage/lcov-report/test-utils/order/entities.ts.html +2 -2
- package/coverage/lcov-report/test-utils/order/index.html +1 -1
- package/coverage/lcov-report/test-utils/order/models/index.html +14 -14
- package/coverage/lcov-report/test-utils/order/models/line-item.ts.html +5 -5
- package/coverage/lcov-report/test-utils/order/models/order.ts.html +36 -36
- package/coverage/lcov-report/test-utils/order/models/product-variant.ts.html +13 -13
- package/coverage/lcov-report/test-utils/order/models/product.ts.html +13 -13
- package/coverage/lcov-report/test-utils/order/models/utm-source.ts.html +8 -8
- package/coverage/lcov-report/test-utils/order-more/entities.ts.html +1 -1
- package/coverage/lcov-report/test-utils/order-more/index.html +1 -1
- package/coverage/lcov-report/test-utils/order-more/models/actual-product-variant.ts.html +3 -3
- package/coverage/lcov-report/test-utils/order-more/models/color.ts.html +6 -6
- package/coverage/lcov-report/test-utils/order-more/models/customer.ts.html +3 -3
- package/coverage/lcov-report/test-utils/order-more/models/gender.ts.html +4 -4
- package/coverage/lcov-report/test-utils/order-more/models/index.html +23 -23
- package/coverage/lcov-report/test-utils/order-more/models/inventory-level.ts.html +11 -11
- package/coverage/lcov-report/test-utils/order-more/models/line-item.ts.html +15 -15
- package/coverage/lcov-report/test-utils/order-more/models/order.ts.html +45 -45
- package/coverage/lcov-report/test-utils/order-more/models/parcel-event.ts.html +6 -6
- package/coverage/lcov-report/test-utils/order-more/models/parcel-line-item.ts.html +7 -7
- package/coverage/lcov-report/test-utils/order-more/models/parcel.ts.html +2 -2
- package/coverage/lcov-report/test-utils/order-more/models/physical-address.ts.html +12 -12
- package/coverage/lcov-report/test-utils/order-more/models/product-variant-image.ts.html +7 -7
- package/coverage/lcov-report/test-utils/order-more/models/product-variant.ts.html +22 -22
- package/coverage/lcov-report/test-utils/order-more/models/product.ts.html +11 -11
- package/coverage/lcov-report/test-utils/order-more/models/refund.ts.html +11 -11
- package/coverage/lcov-report/test-utils/order-more/models/shipment-actual-product-variant.ts.html +9 -9
- package/coverage/lcov-report/test-utils/order-more/models/shipment.ts.html +4 -4
- package/coverage/lcov-report/test-utils/order-more/models/size.ts.html +4 -4
- package/coverage/lcov-report/test-utils/order-more/models/utm-medium.ts.html +15 -15
- package/coverage/lcov-report/test-utils/order-more/models/utm-source.ts.html +17 -17
- package/coverage/lcov-report/test-utils/six/entities.ts.html +1 -1
- package/coverage/lcov-report/test-utils/six/index.html +1 -1
- package/coverage/lcov-report/test-utils/six/models/customer.ts.html +3 -3
- package/coverage/lcov-report/test-utils/six/models/index.html +21 -21
- package/coverage/lcov-report/test-utils/six/models/line-item.ts.html +10 -10
- package/coverage/lcov-report/test-utils/six/models/order.ts.html +13 -13
- package/coverage/lcov-report/test-utils/six/models/parcel-line-item.ts.html +2 -2
- package/coverage/lcov-report/test-utils/six/models/parcel.ts.html +2 -2
- package/coverage/lcov-report/test-utils/thirteen/entities.ts.html +1 -1
- package/coverage/lcov-report/test-utils/thirteen/index.html +1 -1
- package/coverage/lcov-report/test-utils/thirteen/models/audience.ts.html +2 -2
- package/coverage/lcov-report/test-utils/thirteen/models/brand.ts.html +2 -2
- package/coverage/lcov-report/test-utils/thirteen/models/category.ts.html +1 -1
- package/coverage/lcov-report/test-utils/thirteen/models/index.html +14 -14
- package/coverage/lcov-report/test-utils/thirteen/models/member.ts.html +2 -2
- package/coverage/lcov-report/test-utils/thirteen/models/passion.ts.html +2 -2
- package/coverage/lcov-report/test-utils/thirteen/models/product.ts.html +10 -10
- package/coverage/lcov-report/test-utils/thirteen/models/recommendation-audience.ts.html +2 -2
- package/coverage/lcov-report/test-utils/thirteen/models/recommendation.ts.html +2 -2
- package/coverage/lcov-report/test-utils/three/index.html +1 -1
- package/coverage/lcov-report/test-utils/three/results.js.html +1 -1
- package/coverage/lcov-report/test-utils/twelve/entities.ts.html +1 -1
- package/coverage/lcov-report/test-utils/twelve/index.html +1 -1
- package/coverage/lcov-report/test-utils/twelve/models/index.html +1 -1
- package/coverage/lcov-report/test-utils/twelve/models/member.ts.html +1 -1
- package/coverage/lcov-report/test-utils/twelve/models/prompt.ts.html +2 -2
- package/coverage/lcov-report/test-utils/two/index.html +1 -1
- package/coverage/lcov-report/test-utils/two/results.js.html +1 -1
- package/coverage/lcov.info +2134 -1989
- package/dist/src/core.d.ts +6 -0
- package/dist/src/core.js +258 -189
- package/dist/src/core.spec.js +413 -0
- package/dist/src/driver-integrations/pgp.spec.d.ts +1 -0
- package/dist/src/driver-integrations/pgp.spec.js +376 -0
- package/dist/src/orm.d.ts +1 -1
- package/dist/src/orm.js +137 -76
- package/dist/src/orm.spec.js +535 -85
- package/dist/test-utils/nine/models/feature-switch.d.ts +2 -2
- package/dist/test-utils/nine/models/feature-switch.ts +2 -2
- package/package.json +5 -3
- package/scripts/bench-core.js +636 -0
- package/scripts/check-bench-scenarios.js +47 -0
- package/src/core.spec.ts +485 -2
- package/src/core.ts +369 -227
- package/src/driver-integrations/pgp.spec.ts +444 -0
- package/src/orm.spec.ts +592 -88
- package/src/orm.ts +149 -128
- package/test-utils/nine/models/feature-switch.ts +2 -2
|
@@ -5,13 +5,13 @@ export const tableName: string = 'feature_switch';
|
|
|
5
5
|
export const columns: IColumns = ['id', 'label', 'on'];
|
|
6
6
|
|
|
7
7
|
interface IFeatureSwitchProps {
|
|
8
|
-
id: number;
|
|
8
|
+
id: string | number;
|
|
9
9
|
label: string;
|
|
10
10
|
on: boolean;
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
export class FeatureSwitch implements IModel {
|
|
14
|
-
id: number;
|
|
14
|
+
id: string | number;
|
|
15
15
|
label: string;
|
|
16
16
|
on: boolean;
|
|
17
17
|
|
package/package.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pure-orm",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.1.4",
|
|
4
4
|
"main": "dist/src/index.js",
|
|
5
5
|
"types": "dist/src/index.d.ts",
|
|
6
6
|
"engines": {
|
|
7
7
|
"node": ">=6"
|
|
8
8
|
},
|
|
9
9
|
"scripts": {
|
|
10
|
-
"test": "npm run test:unit && npm run test:format",
|
|
10
|
+
"test": "npm run test:unit && npm run test:bench-guard && npm run test:format",
|
|
11
11
|
"test:unit": "npm run build && jest",
|
|
12
12
|
"test:unit:watch": "jest --watch",
|
|
13
13
|
"test:unit:debug": "node --inspect-brk node_modules/.bin/jest --runInBand --verbose",
|
|
@@ -16,7 +16,9 @@
|
|
|
16
16
|
"lint": "eslint .",
|
|
17
17
|
"pub": "npm run test && npm run build && np",
|
|
18
18
|
"build": "rm -rf dist && mkdir -p dist && cp -r test-utils dist/test-utils && tsc",
|
|
19
|
-
"build:watch": "rm -rf dist && mkdir -p dist && cp -r test-utils dist/test-utils && tsc --watch"
|
|
19
|
+
"build:watch": "rm -rf dist && mkdir -p dist && cp -r test-utils dist/test-utils && tsc --watch",
|
|
20
|
+
"bench:core": "npm run build && node scripts/bench-core.js",
|
|
21
|
+
"test:bench-guard": "node scripts/check-bench-scenarios.js"
|
|
20
22
|
},
|
|
21
23
|
"dependencies": {
|
|
22
24
|
"@babel/core": "^7.17.9",
|
|
@@ -0,0 +1,636 @@
|
|
|
1
|
+
/* eslint-disable no-console */
|
|
2
|
+
const fs = require('fs');
|
|
3
|
+
const path = require('path');
|
|
4
|
+
const { createCore } = require('../dist/src/core');
|
|
5
|
+
const { create: createOrm } = require('../dist/src/orm');
|
|
6
|
+
const {
|
|
7
|
+
entities: orderEntities
|
|
8
|
+
} = require('../dist/test-utils/order/entities');
|
|
9
|
+
const { entities: blogEntities } = require('../dist/test-utils/blog/entities');
|
|
10
|
+
const {
|
|
11
|
+
entities: orderMoreEntities
|
|
12
|
+
} = require('../dist/test-utils/order-more/entities');
|
|
13
|
+
const { entities: nineEntities } = require('../dist/test-utils/nine/entities');
|
|
14
|
+
const { entities: fiveEntities } = require('../dist/test-utils/five/entities');
|
|
15
|
+
const { entities: sixEntities } = require('../dist/test-utils/six/entities');
|
|
16
|
+
const {
|
|
17
|
+
entities: twelveEntities
|
|
18
|
+
} = require('../dist/test-utils/twelve/entities');
|
|
19
|
+
const {
|
|
20
|
+
entities: thirteenEntities
|
|
21
|
+
} = require('../dist/test-utils/thirteen/entities');
|
|
22
|
+
const {
|
|
23
|
+
entities: fourteenEntities
|
|
24
|
+
} = require('../dist/test-utils/fourteen/entities');
|
|
25
|
+
|
|
26
|
+
const two = require('../dist/test-utils/two/results');
|
|
27
|
+
const three = require('../dist/test-utils/three/results');
|
|
28
|
+
const one = require('../dist/test-utils/one/results.json');
|
|
29
|
+
const four = require('../dist/test-utils/four/results.json');
|
|
30
|
+
const five = require('../dist/test-utils/five/results.json');
|
|
31
|
+
const six = require('../dist/test-utils/six/results.json');
|
|
32
|
+
const seven = require('../dist/test-utils/seven/results.json');
|
|
33
|
+
const eight = require('../dist/test-utils/eight/results.json');
|
|
34
|
+
const nine = require('../dist/test-utils/nine/results.json');
|
|
35
|
+
const ten = require('../dist/test-utils/ten/results.json');
|
|
36
|
+
const eleven = require('../dist/test-utils/eleven/results.json');
|
|
37
|
+
const twelve = require('../dist/test-utils/twelve/results.json');
|
|
38
|
+
const thirteen = require('../dist/test-utils/thirteen/results.json');
|
|
39
|
+
const fourteen = require('../dist/test-utils/fourteen/results.json');
|
|
40
|
+
const { Order } = require('../dist/test-utils/order/models/order');
|
|
41
|
+
|
|
42
|
+
const SAMPLE_COUNT = Number(process.env.BENCH_SAMPLES || 5);
|
|
43
|
+
const HELPER_ITERATIONS = Number(process.env.BENCH_HELPER_ITERS || 300000);
|
|
44
|
+
const SAVE_BASELINE_PATH = process.env.BENCH_SAVE_BASELINE || '';
|
|
45
|
+
const COMPARE_BASELINE_PATH = process.env.BENCH_COMPARE_BASELINE || '';
|
|
46
|
+
const BENCH_SEED = Number(process.env.BENCH_SEED || 1337);
|
|
47
|
+
|
|
48
|
+
const FIXTURE_CASES = [
|
|
49
|
+
{ label: 'order/one', entities: orderEntities, rows: one },
|
|
50
|
+
{ label: 'blog/two', entities: blogEntities, rows: two },
|
|
51
|
+
{ label: 'blog/three', entities: blogEntities, rows: three },
|
|
52
|
+
{ label: 'order-more/four', entities: orderMoreEntities, rows: four },
|
|
53
|
+
{ label: 'five/five', entities: fiveEntities, rows: five },
|
|
54
|
+
{ label: 'six/six', entities: sixEntities, rows: six },
|
|
55
|
+
{ label: 'order-more/seven', entities: orderMoreEntities, rows: seven },
|
|
56
|
+
{ label: 'order-more/eight', entities: orderMoreEntities, rows: eight },
|
|
57
|
+
{ label: 'nine/nine', entities: nineEntities, rows: nine },
|
|
58
|
+
{ label: 'order-more/ten', entities: orderMoreEntities, rows: ten },
|
|
59
|
+
{ label: 'order-more/eleven', entities: orderMoreEntities, rows: eleven },
|
|
60
|
+
{ label: 'twelve/twelve', entities: twelveEntities, rows: twelve },
|
|
61
|
+
{ label: 'thirteen/thirteen', entities: thirteenEntities, rows: thirteen },
|
|
62
|
+
{ label: 'fourteen/fourteen', entities: fourteenEntities, rows: fourteen }
|
|
63
|
+
];
|
|
64
|
+
|
|
65
|
+
const STRESS_SCENARIOS = [
|
|
66
|
+
{
|
|
67
|
+
label: 'stress/same-root x120',
|
|
68
|
+
entities: orderMoreEntities,
|
|
69
|
+
baseRows: eleven,
|
|
70
|
+
multiplier: 120,
|
|
71
|
+
distributeRoots: false,
|
|
72
|
+
sparseJoins: false,
|
|
73
|
+
rounds: 5
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
label: 'stress/many-roots x120',
|
|
77
|
+
entities: orderMoreEntities,
|
|
78
|
+
baseRows: eleven,
|
|
79
|
+
multiplier: 120,
|
|
80
|
+
distributeRoots: true,
|
|
81
|
+
sparseJoins: false,
|
|
82
|
+
rounds: 5
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
label: 'stress/sparse-joins x120',
|
|
86
|
+
entities: orderMoreEntities,
|
|
87
|
+
baseRows: eleven,
|
|
88
|
+
multiplier: 120,
|
|
89
|
+
distributeRoots: false,
|
|
90
|
+
sparseJoins: true,
|
|
91
|
+
rounds: 8
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
label: 'stress/sparse-many x120',
|
|
95
|
+
entities: orderMoreEntities,
|
|
96
|
+
baseRows: eleven,
|
|
97
|
+
multiplier: 120,
|
|
98
|
+
distributeRoots: true,
|
|
99
|
+
sparseJoins: true,
|
|
100
|
+
rounds: 8
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
label: 'stress/unstable-order x120',
|
|
104
|
+
entities: orderMoreEntities,
|
|
105
|
+
baseRows: eleven,
|
|
106
|
+
multiplier: 120,
|
|
107
|
+
distributeRoots: false,
|
|
108
|
+
unstableColumnOrder: true,
|
|
109
|
+
rounds: 8
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
label: 'stress/unstable-many x120',
|
|
113
|
+
entities: orderMoreEntities,
|
|
114
|
+
baseRows: eleven,
|
|
115
|
+
multiplier: 120,
|
|
116
|
+
distributeRoots: true,
|
|
117
|
+
unstableColumnOrder: true,
|
|
118
|
+
rounds: 8
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
label: 'stress/mixed-fixtures x80',
|
|
122
|
+
entities: orderMoreEntities,
|
|
123
|
+
baseRowsSet: [seven, eight, ten, eleven],
|
|
124
|
+
multiplier: 80,
|
|
125
|
+
distributeRoots: true,
|
|
126
|
+
sparseJoins: false,
|
|
127
|
+
shuffleRows: true,
|
|
128
|
+
rounds: 6
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
label: 'stress/mixed-sparse x80',
|
|
132
|
+
entities: orderMoreEntities,
|
|
133
|
+
baseRowsSet: [seven, eight, ten, eleven],
|
|
134
|
+
multiplier: 80,
|
|
135
|
+
distributeRoots: true,
|
|
136
|
+
sparseJoins: true,
|
|
137
|
+
shuffleRows: true,
|
|
138
|
+
rounds: 8
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
label: 'stress/composite-pk x120',
|
|
142
|
+
entities: null,
|
|
143
|
+
baseRows: null,
|
|
144
|
+
multiplier: 120,
|
|
145
|
+
distributeRoots: false,
|
|
146
|
+
compositePk: true,
|
|
147
|
+
rounds: 8
|
|
148
|
+
}
|
|
149
|
+
];
|
|
150
|
+
|
|
151
|
+
const createRng = (seed) => {
|
|
152
|
+
let state = seed >>> 0 || 1;
|
|
153
|
+
return () => {
|
|
154
|
+
state = (state * 1664525 + 1013904223) >>> 0;
|
|
155
|
+
return state / 0x100000000;
|
|
156
|
+
};
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
const shuffleInPlace = (items, random) => {
|
|
160
|
+
for (let i = items.length - 1; i > 0; i--) {
|
|
161
|
+
const j = Math.floor(random() * (i + 1));
|
|
162
|
+
const tmp = items[i];
|
|
163
|
+
items[i] = items[j];
|
|
164
|
+
items[j] = tmp;
|
|
165
|
+
}
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
const sparsifyRow = ({ row, rootTablePrefix }) => {
|
|
169
|
+
const sparse = {};
|
|
170
|
+
for (const key in row) {
|
|
171
|
+
if (!Object.prototype.hasOwnProperty.call(row, key)) {
|
|
172
|
+
continue;
|
|
173
|
+
}
|
|
174
|
+
sparse[key] = key.startsWith(`${rootTablePrefix}#`) ? row[key] : null;
|
|
175
|
+
}
|
|
176
|
+
return sparse;
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
const reorderRowKeys = (row) => {
|
|
180
|
+
const keys = Object.keys(row);
|
|
181
|
+
const reordered = {};
|
|
182
|
+
for (let i = 0; i < keys.length; i++) {
|
|
183
|
+
const idx = (i * 7 + 3) % keys.length;
|
|
184
|
+
const key = keys[idx];
|
|
185
|
+
reordered[key] = row[key];
|
|
186
|
+
}
|
|
187
|
+
return reordered;
|
|
188
|
+
};
|
|
189
|
+
|
|
190
|
+
const createCompositePkScenario = ({ multiplier }) => {
|
|
191
|
+
class CompositeRoot {
|
|
192
|
+
constructor(props) {
|
|
193
|
+
Object.assign(this, props);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
class CompositeRoots {
|
|
197
|
+
constructor({ models }) {
|
|
198
|
+
this.models = models;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
class CompositeChild {
|
|
202
|
+
constructor(props) {
|
|
203
|
+
Object.assign(this, props);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
class CompositeChildren {
|
|
207
|
+
constructor({ models }) {
|
|
208
|
+
this.models = models;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
const entities = [
|
|
213
|
+
{
|
|
214
|
+
tableName: 'comp_root',
|
|
215
|
+
columns: [
|
|
216
|
+
{ column: 'tenant_id', primaryKey: true },
|
|
217
|
+
{ column: 'order_id', primaryKey: true },
|
|
218
|
+
'label'
|
|
219
|
+
],
|
|
220
|
+
Model: CompositeRoot,
|
|
221
|
+
Collection: CompositeRoots
|
|
222
|
+
},
|
|
223
|
+
{
|
|
224
|
+
tableName: 'comp_child',
|
|
225
|
+
columns: [
|
|
226
|
+
'id',
|
|
227
|
+
{ column: 'root_key', references: CompositeRoot },
|
|
228
|
+
'value'
|
|
229
|
+
],
|
|
230
|
+
Model: CompositeChild,
|
|
231
|
+
Collection: CompositeChildren
|
|
232
|
+
}
|
|
233
|
+
];
|
|
234
|
+
|
|
235
|
+
const rows = [];
|
|
236
|
+
let childId = 1;
|
|
237
|
+
for (let m = 0; m < multiplier; m++) {
|
|
238
|
+
for (let tenantId = 1; tenantId <= 20; tenantId++) {
|
|
239
|
+
const orderId = m + 1000;
|
|
240
|
+
const rootKey = `${tenantId}${orderId}`;
|
|
241
|
+
for (let c = 0; c < 3; c++) {
|
|
242
|
+
rows.push({
|
|
243
|
+
'comp_root#tenant_id': tenantId,
|
|
244
|
+
'comp_root#order_id': orderId,
|
|
245
|
+
'comp_root#label': `r-${tenantId}-${orderId}`,
|
|
246
|
+
'comp_child#id': childId++,
|
|
247
|
+
'comp_child#root_key': rootKey,
|
|
248
|
+
'comp_child#value': `v-${c}`
|
|
249
|
+
});
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
return { entities, rows };
|
|
254
|
+
};
|
|
255
|
+
|
|
256
|
+
const buildStressRows = ({
|
|
257
|
+
baseRows,
|
|
258
|
+
baseRowsSet,
|
|
259
|
+
multiplier,
|
|
260
|
+
distributeRoots,
|
|
261
|
+
sparseJoins = false,
|
|
262
|
+
unstableColumnOrder = false,
|
|
263
|
+
shuffleRows = false,
|
|
264
|
+
rng
|
|
265
|
+
}) => {
|
|
266
|
+
const sourceRows = baseRowsSet ? baseRowsSet.flat() : baseRows;
|
|
267
|
+
const rows = [];
|
|
268
|
+
const firstKey = Object.keys(sourceRows[0]).find((k) => k.endsWith('#id'));
|
|
269
|
+
const rootTable = firstKey ? firstKey.split('#')[0] : 'order';
|
|
270
|
+
for (let i = 0; i < multiplier; i++) {
|
|
271
|
+
for (const row of sourceRows) {
|
|
272
|
+
let base = sparseJoins
|
|
273
|
+
? sparsifyRow({ row, rootTablePrefix: rootTable })
|
|
274
|
+
: row;
|
|
275
|
+
if (unstableColumnOrder) {
|
|
276
|
+
base = reorderRowKeys(base);
|
|
277
|
+
}
|
|
278
|
+
const cloned = { ...base };
|
|
279
|
+
if (distributeRoots) {
|
|
280
|
+
const rootIdKey = `${rootTable}#id`;
|
|
281
|
+
cloned[rootIdKey] = row[rootIdKey] + (i + 1) * 10000;
|
|
282
|
+
}
|
|
283
|
+
rows.push(cloned);
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
if (shuffleRows && rows.length > 1) {
|
|
287
|
+
shuffleInPlace(rows, rng || Math.random);
|
|
288
|
+
}
|
|
289
|
+
return rows;
|
|
290
|
+
};
|
|
291
|
+
|
|
292
|
+
const runBench = ({ label, rows, rounds, core }) => {
|
|
293
|
+
// Warm JIT and hidden classes before timing.
|
|
294
|
+
core.createFromDatabase(rows);
|
|
295
|
+
const samples = [];
|
|
296
|
+
for (let sample = 0; sample < SAMPLE_COUNT; sample++) {
|
|
297
|
+
if (global.gc) {
|
|
298
|
+
global.gc();
|
|
299
|
+
}
|
|
300
|
+
const start = process.hrtime.bigint();
|
|
301
|
+
for (let i = 0; i < rounds; i++) {
|
|
302
|
+
core.createFromDatabase(rows);
|
|
303
|
+
}
|
|
304
|
+
const elapsedMs = Number(process.hrtime.bigint() - start) / 1e6;
|
|
305
|
+
samples.push(elapsedMs);
|
|
306
|
+
}
|
|
307
|
+
const sortedSamples = [...samples].sort((a, b) => a - b);
|
|
308
|
+
const medianElapsedMs = sortedSamples[Math.floor(sortedSamples.length / 2)];
|
|
309
|
+
const minElapsedMs = sortedSamples[0];
|
|
310
|
+
const maxElapsedMs = sortedSamples[sortedSamples.length - 1];
|
|
311
|
+
const meanElapsedMs = samples.reduce((acc, n) => acc + n, 0) / samples.length;
|
|
312
|
+
const perIterMs = medianElapsedMs / rounds;
|
|
313
|
+
const rowsPerSecond = (rows.length * rounds * 1000) / medianElapsedMs;
|
|
314
|
+
return {
|
|
315
|
+
label,
|
|
316
|
+
rows: rows.length,
|
|
317
|
+
rounds,
|
|
318
|
+
samples: SAMPLE_COUNT,
|
|
319
|
+
medianElapsedMs,
|
|
320
|
+
meanElapsedMs,
|
|
321
|
+
minElapsedMs,
|
|
322
|
+
maxElapsedMs,
|
|
323
|
+
perIterMs,
|
|
324
|
+
rowsPerSecond
|
|
325
|
+
};
|
|
326
|
+
};
|
|
327
|
+
|
|
328
|
+
const format = (n, decimals = 2) => n.toFixed(decimals);
|
|
329
|
+
const formatPercent = (n) => `${n > 0 ? '+' : ''}${format(n, 2)}%`;
|
|
330
|
+
const geometricMean = (values) => {
|
|
331
|
+
const positives = values.filter((v) => v > 0);
|
|
332
|
+
if (positives.length === 0) {
|
|
333
|
+
return 0;
|
|
334
|
+
}
|
|
335
|
+
let sum = 0;
|
|
336
|
+
for (let i = 0; i < positives.length; i++) {
|
|
337
|
+
sum += Math.log(positives[i]);
|
|
338
|
+
}
|
|
339
|
+
return Math.exp(sum / positives.length);
|
|
340
|
+
};
|
|
341
|
+
const indexByLabel = (items) => {
|
|
342
|
+
const index = new Map();
|
|
343
|
+
for (let i = 0; i < items.length; i++) {
|
|
344
|
+
index.set(items[i].label, items[i]);
|
|
345
|
+
}
|
|
346
|
+
return index;
|
|
347
|
+
};
|
|
348
|
+
|
|
349
|
+
const printDeltaTable = ({
|
|
350
|
+
title,
|
|
351
|
+
currentItems,
|
|
352
|
+
baselineItems,
|
|
353
|
+
metric,
|
|
354
|
+
unit
|
|
355
|
+
}) => {
|
|
356
|
+
const baselineByLabel = indexByLabel(baselineItems);
|
|
357
|
+
console.log(`\n${title}`);
|
|
358
|
+
for (let i = 0; i < currentItems.length; i++) {
|
|
359
|
+
const current = currentItems[i];
|
|
360
|
+
const baseline = baselineByLabel.get(current.label);
|
|
361
|
+
if (!baseline || !baseline[metric]) {
|
|
362
|
+
console.log(`${current.label.padEnd(30)} | baseline: n/a`);
|
|
363
|
+
continue;
|
|
364
|
+
}
|
|
365
|
+
const baselineValue = baseline[metric];
|
|
366
|
+
const currentValue = current[metric];
|
|
367
|
+
const deltaPct = ((currentValue - baselineValue) / baselineValue) * 100;
|
|
368
|
+
console.log(
|
|
369
|
+
`${current.label.padEnd(30)} | ${format(
|
|
370
|
+
baselineValue,
|
|
371
|
+
metric === 'rowsPerSecond' || metric === 'opsPerSec' ? 0 : 2
|
|
372
|
+
)} -> ${format(
|
|
373
|
+
currentValue,
|
|
374
|
+
metric === 'rowsPerSecond' || metric === 'opsPerSec' ? 0 : 2
|
|
375
|
+
)} ${unit} (${formatPercent(deltaPct)})`
|
|
376
|
+
);
|
|
377
|
+
}
|
|
378
|
+
};
|
|
379
|
+
|
|
380
|
+
const saveBaseline = ({ outputPath, payload }) => {
|
|
381
|
+
const resolved = path.resolve(outputPath);
|
|
382
|
+
fs.mkdirSync(path.dirname(resolved), { recursive: true });
|
|
383
|
+
fs.writeFileSync(resolved, JSON.stringify(payload, null, 2));
|
|
384
|
+
console.log(`\nSaved baseline: ${resolved}`);
|
|
385
|
+
};
|
|
386
|
+
|
|
387
|
+
const loadBaseline = (inputPath) => {
|
|
388
|
+
const resolved = path.resolve(inputPath);
|
|
389
|
+
const raw = fs.readFileSync(resolved, 'utf8');
|
|
390
|
+
return { resolved, data: JSON.parse(raw) };
|
|
391
|
+
};
|
|
392
|
+
|
|
393
|
+
const main = () => {
|
|
394
|
+
const rng = createRng(BENCH_SEED);
|
|
395
|
+
console.log('Pure ORM core.createFromDatabase benchmark');
|
|
396
|
+
console.log(
|
|
397
|
+
'Coverage: all core.spec test-utils fixtures + stress scenarios\n'
|
|
398
|
+
);
|
|
399
|
+
console.log(
|
|
400
|
+
`Sampling: ${SAMPLE_COUNT} samples/scenario, ${
|
|
401
|
+
global.gc ? 'GC enabled' : 'GC not enabled'
|
|
402
|
+
}, seed=${BENCH_SEED}`
|
|
403
|
+
);
|
|
404
|
+
if (SAVE_BASELINE_PATH) {
|
|
405
|
+
console.log(`Save baseline: ${path.resolve(SAVE_BASELINE_PATH)}`);
|
|
406
|
+
}
|
|
407
|
+
if (COMPARE_BASELINE_PATH) {
|
|
408
|
+
console.log(`Compare baseline: ${path.resolve(COMPARE_BASELINE_PATH)}`);
|
|
409
|
+
}
|
|
410
|
+
console.log('');
|
|
411
|
+
|
|
412
|
+
const fixtureResults = FIXTURE_CASES.map((fixture) => {
|
|
413
|
+
const core = createCore({ entities: fixture.entities });
|
|
414
|
+
const rounds = 200;
|
|
415
|
+
return runBench({
|
|
416
|
+
label: fixture.label,
|
|
417
|
+
rows: fixture.rows,
|
|
418
|
+
rounds,
|
|
419
|
+
core
|
|
420
|
+
});
|
|
421
|
+
});
|
|
422
|
+
|
|
423
|
+
console.log('Fixture scenarios');
|
|
424
|
+
for (const r of fixtureResults) {
|
|
425
|
+
console.log(
|
|
426
|
+
`${r.label.padEnd(22)} | rows=${String(r.rows).padStart(
|
|
427
|
+
4
|
|
428
|
+
)} | rounds=${String(r.rounds).padStart(3)} | ${format(
|
|
429
|
+
r.perIterMs,
|
|
430
|
+
4
|
|
431
|
+
)} ms/iter | ${format(r.rowsPerSecond, 0)} rows/sec | med=${format(
|
|
432
|
+
r.medianElapsedMs,
|
|
433
|
+
2
|
|
434
|
+
)}ms mean=${format(r.meanElapsedMs, 2)}ms min=${format(
|
|
435
|
+
r.minElapsedMs,
|
|
436
|
+
2
|
|
437
|
+
)}ms max=${format(r.maxElapsedMs, 2)}ms`
|
|
438
|
+
);
|
|
439
|
+
}
|
|
440
|
+
const fixtureGeomean = geometricMean(
|
|
441
|
+
fixtureResults.map((r) => r.rowsPerSecond)
|
|
442
|
+
);
|
|
443
|
+
console.log(`fixture geomean rows/sec: ${format(fixtureGeomean, 0)}\n`);
|
|
444
|
+
|
|
445
|
+
const stressResults = STRESS_SCENARIOS.map((scenario) => {
|
|
446
|
+
let entities = scenario.entities;
|
|
447
|
+
let rows;
|
|
448
|
+
if (scenario.compositePk) {
|
|
449
|
+
const composite = createCompositePkScenario({
|
|
450
|
+
multiplier: scenario.multiplier
|
|
451
|
+
});
|
|
452
|
+
entities = composite.entities;
|
|
453
|
+
rows = composite.rows;
|
|
454
|
+
} else {
|
|
455
|
+
rows = buildStressRows({ ...scenario, rng });
|
|
456
|
+
}
|
|
457
|
+
const core = createCore({ entities });
|
|
458
|
+
return runBench({
|
|
459
|
+
label: scenario.label,
|
|
460
|
+
rows,
|
|
461
|
+
rounds: scenario.rounds,
|
|
462
|
+
core
|
|
463
|
+
});
|
|
464
|
+
});
|
|
465
|
+
|
|
466
|
+
console.log('Stress scenarios');
|
|
467
|
+
for (const r of stressResults) {
|
|
468
|
+
console.log(
|
|
469
|
+
`${r.label.padEnd(22)} | rows=${String(r.rows).padStart(
|
|
470
|
+
5
|
|
471
|
+
)} | rounds=${String(r.rounds).padStart(2)} | ${format(
|
|
472
|
+
r.perIterMs
|
|
473
|
+
)} ms/iter | ${format(r.rowsPerSecond, 0)} rows/sec | med=${format(
|
|
474
|
+
r.medianElapsedMs,
|
|
475
|
+
2
|
|
476
|
+
)}ms mean=${format(r.meanElapsedMs, 2)}ms min=${format(
|
|
477
|
+
r.minElapsedMs,
|
|
478
|
+
2
|
|
479
|
+
)}ms max=${format(r.maxElapsedMs, 2)}ms`
|
|
480
|
+
);
|
|
481
|
+
}
|
|
482
|
+
const stressGeomean = geometricMean(
|
|
483
|
+
stressResults.map((r) => r.rowsPerSecond)
|
|
484
|
+
);
|
|
485
|
+
console.log(`stress geomean rows/sec: ${format(stressGeomean, 0)}`);
|
|
486
|
+
|
|
487
|
+
const fakeDb = {
|
|
488
|
+
$config: { pgp: true },
|
|
489
|
+
many: () => Promise.resolve([]),
|
|
490
|
+
any: () => Promise.resolve([]),
|
|
491
|
+
result: () => Promise.resolve({ rows: [], fields: [{ name: 'order#id' }] }),
|
|
492
|
+
none: () => Promise.resolve()
|
|
493
|
+
};
|
|
494
|
+
const orm = createOrm({ entities: orderEntities, db: fakeDb });
|
|
495
|
+
const benchmarkOrders = Array.from({ length: 32 }, (_, i) => {
|
|
496
|
+
const ts = 1700000000000 + i * 86400000;
|
|
497
|
+
return new Order({
|
|
498
|
+
id: i + 1,
|
|
499
|
+
email: `user${i}@example.com`,
|
|
500
|
+
browserIp: `127.0.0.${(i % 250) + 1}`,
|
|
501
|
+
browserUserAgent: `ua-${i % 5}`,
|
|
502
|
+
kujoImportedDate: new Date(ts),
|
|
503
|
+
createdDate: new Date(ts - 1000),
|
|
504
|
+
cancelReason: i % 7 === 0 ? 'test' : null,
|
|
505
|
+
cancelledDate: i % 7 === 0 ? new Date(ts + 5000) : null,
|
|
506
|
+
closedDate: null,
|
|
507
|
+
processedDate: new Date(ts + 1000),
|
|
508
|
+
updatedDate: new Date(ts + 2000),
|
|
509
|
+
note: `n-${i}`,
|
|
510
|
+
subtotalPrice: i + 1,
|
|
511
|
+
taxesIncluded: i % 2 === 0,
|
|
512
|
+
totalDiscounts: i % 3,
|
|
513
|
+
totalPrice: i + 2,
|
|
514
|
+
totalTax: i % 5,
|
|
515
|
+
totalWeight: i % 11,
|
|
516
|
+
orderStatusUrl: `url-${i}`,
|
|
517
|
+
utmSourceId: (i % 4) + 1,
|
|
518
|
+
utmMediumId: (i % 6) + 1,
|
|
519
|
+
utmCampaign: `camp-${i % 3}`,
|
|
520
|
+
utmContent: `content-${i % 8}`,
|
|
521
|
+
utmTerm: `term-${i % 9}`
|
|
522
|
+
});
|
|
523
|
+
});
|
|
524
|
+
const benchmarkProperties = [
|
|
525
|
+
'updatedDate',
|
|
526
|
+
'email',
|
|
527
|
+
'totalPrice',
|
|
528
|
+
'utmCampaign'
|
|
529
|
+
];
|
|
530
|
+
const ormHelperScenarios = [
|
|
531
|
+
{
|
|
532
|
+
label: 'orm/getSqlInsertParts',
|
|
533
|
+
fn: (i) => orm.getSqlInsertParts(benchmarkOrders[i & 31])
|
|
534
|
+
},
|
|
535
|
+
{
|
|
536
|
+
label: 'orm/getSqlUpdateParts',
|
|
537
|
+
fn: (i) => orm.getSqlUpdateParts(benchmarkOrders[i & 31], 'id')
|
|
538
|
+
},
|
|
539
|
+
{
|
|
540
|
+
label: 'orm/getMatchingParts',
|
|
541
|
+
fn: (i) => orm.getMatchingParts(benchmarkOrders[i & 31])
|
|
542
|
+
},
|
|
543
|
+
{
|
|
544
|
+
label: 'orm/getMatchingPartsObject',
|
|
545
|
+
fn: (i) => orm.getMatchingPartsObject(benchmarkOrders[i & 31])
|
|
546
|
+
},
|
|
547
|
+
{
|
|
548
|
+
label: 'orm/getSqlColumnForPropertyName',
|
|
549
|
+
fn: (i) =>
|
|
550
|
+
orm.getSqlColumnForPropertyName(
|
|
551
|
+
benchmarkOrders[i & 31],
|
|
552
|
+
benchmarkProperties[i % benchmarkProperties.length]
|
|
553
|
+
)
|
|
554
|
+
}
|
|
555
|
+
];
|
|
556
|
+
console.log('\nORM helper microbench');
|
|
557
|
+
const ormHelperResults = [];
|
|
558
|
+
for (const scenario of ormHelperScenarios) {
|
|
559
|
+
const sampleMs = [];
|
|
560
|
+
for (let sample = 0; sample < SAMPLE_COUNT; sample++) {
|
|
561
|
+
scenario.fn(0);
|
|
562
|
+
if (global.gc) {
|
|
563
|
+
global.gc();
|
|
564
|
+
}
|
|
565
|
+
const start = process.hrtime.bigint();
|
|
566
|
+
for (let i = 0; i < HELPER_ITERATIONS; i++) {
|
|
567
|
+
scenario.fn(i);
|
|
568
|
+
}
|
|
569
|
+
sampleMs.push(Number(process.hrtime.bigint() - start) / 1e6);
|
|
570
|
+
}
|
|
571
|
+
const sorted = [...sampleMs].sort((a, b) => a - b);
|
|
572
|
+
const medianMs = sorted[Math.floor(sorted.length / 2)];
|
|
573
|
+
const minMs = sorted[0];
|
|
574
|
+
const maxMs = sorted[sorted.length - 1];
|
|
575
|
+
const meanMs = sampleMs.reduce((acc, n) => acc + n, 0) / sampleMs.length;
|
|
576
|
+
const opsPerSec = (HELPER_ITERATIONS * 1000) / medianMs;
|
|
577
|
+
ormHelperResults.push({
|
|
578
|
+
label: scenario.label,
|
|
579
|
+
medianMs,
|
|
580
|
+
meanMs,
|
|
581
|
+
minMs,
|
|
582
|
+
maxMs,
|
|
583
|
+
opsPerSec
|
|
584
|
+
});
|
|
585
|
+
console.log(
|
|
586
|
+
`${scenario.label.padEnd(30)} | ${format(
|
|
587
|
+
medianMs,
|
|
588
|
+
2
|
|
589
|
+
)} ms total (median) | ${format(opsPerSec, 0)} ops/sec | mean=${format(
|
|
590
|
+
meanMs,
|
|
591
|
+
2
|
|
592
|
+
)}ms min=${format(minMs, 2)}ms max=${format(maxMs, 2)}ms`
|
|
593
|
+
);
|
|
594
|
+
}
|
|
595
|
+
|
|
596
|
+
const payload = {
|
|
597
|
+
generatedAt: new Date().toISOString(),
|
|
598
|
+
sampleCount: SAMPLE_COUNT,
|
|
599
|
+
helperIterations: HELPER_ITERATIONS,
|
|
600
|
+
fixtureResults,
|
|
601
|
+
stressResults,
|
|
602
|
+
ormHelperResults
|
|
603
|
+
};
|
|
604
|
+
|
|
605
|
+
if (SAVE_BASELINE_PATH) {
|
|
606
|
+
saveBaseline({ outputPath: SAVE_BASELINE_PATH, payload });
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
if (COMPARE_BASELINE_PATH) {
|
|
610
|
+
const baseline = loadBaseline(COMPARE_BASELINE_PATH);
|
|
611
|
+
console.log(`\nLoaded baseline: ${baseline.resolved}`);
|
|
612
|
+
printDeltaTable({
|
|
613
|
+
title: 'Fixture rows/sec delta vs baseline',
|
|
614
|
+
currentItems: fixtureResults,
|
|
615
|
+
baselineItems: baseline.data.fixtureResults || [],
|
|
616
|
+
metric: 'rowsPerSecond',
|
|
617
|
+
unit: 'rows/sec'
|
|
618
|
+
});
|
|
619
|
+
printDeltaTable({
|
|
620
|
+
title: 'Stress rows/sec delta vs baseline',
|
|
621
|
+
currentItems: stressResults,
|
|
622
|
+
baselineItems: baseline.data.stressResults || [],
|
|
623
|
+
metric: 'rowsPerSecond',
|
|
624
|
+
unit: 'rows/sec'
|
|
625
|
+
});
|
|
626
|
+
printDeltaTable({
|
|
627
|
+
title: 'ORM helper ops/sec delta vs baseline',
|
|
628
|
+
currentItems: ormHelperResults,
|
|
629
|
+
baselineItems: baseline.data.ormHelperResults || [],
|
|
630
|
+
metric: 'opsPerSec',
|
|
631
|
+
unit: 'ops/sec'
|
|
632
|
+
});
|
|
633
|
+
}
|
|
634
|
+
};
|
|
635
|
+
|
|
636
|
+
main();
|