Skip to content

Commit bc6baed

Browse files
committed
add a mechanism for performance testing
added a couple of performance tests made a couple of performance fixes
1 parent 93c9b4f commit bc6baed

File tree

8 files changed

+111
-25
lines changed

8 files changed

+111
-25
lines changed

npm-shrinkwrap.json

Lines changed: 3 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
"eslint-config-airbnb-base": "^15.0.0",
4141
"eslint-plugin-import": "^2.29.1",
4242
"eslint-plugin-jest": "^27.6.0",
43+
"express": "^4.18.2",
4344
"html-inline-script-webpack-plugin": "^3.1.0",
4445
"html-webpack-plugin": "^5.6.0",
4546
"jest": "^29.3.1",

src/TreeInterpreter.js

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ export default class TreeInterpreter {
7272
this.toString = toString;
7373
this.debug = debug;
7474
this.language = language;
75+
this.visitFunctions = this.initVisitFunctions();
7576
}
7677

7778
search(node, value) {
@@ -93,8 +94,8 @@ export default class TreeInterpreter {
9394
return null;
9495
}
9596

96-
visit(n, v = null) {
97-
const visitFunctions = {
97+
initVisitFunctions() {
98+
return {
9899
Identifier: this.field.bind(this),
99100
QuotedIdentifier: this.field.bind(this),
100101

@@ -399,7 +400,10 @@ export default class TreeInterpreter {
399400
return refNode;
400401
},
401402
};
402-
const fn = n && visitFunctions[n.type];
403+
}
404+
405+
visit(n, v = null) {
406+
const fn = n && this.visitFunctions[n.type];
403407
return fn(n, v);
404408
}
405409

src/matchType.js

Lines changed: 18 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -56,32 +56,30 @@ function isArray(t) {
5656
}
5757

5858
export function getType(inputObj) {
59-
if (inputObj === null) return TYPE_NULL;
60-
// if inputObj is a class, then convert it to its base type via JSON
61-
const obj = JSON.parse(JSON.stringify(inputObj));
62-
switch (Object.prototype.toString.call(obj)) {
63-
case '[object String]':
64-
return TYPE_STRING;
65-
case '[object Number]':
66-
return TYPE_NUMBER;
67-
case '[object Array]':
59+
function simpleType(obj) {
60+
if (obj === null) return TYPE_NULL;
61+
const t = typeof obj;
62+
if (t === 'string') return TYPE_STRING;
63+
if (t === 'number') return TYPE_NUMBER;
64+
if (t === 'boolean') return TYPE_BOOLEAN;
65+
if (Array.isArray(obj)) {
6866
if (obj.length === 0) return TYPE_EMPTY_ARRAY;
6967
if (obj.every(a => isArray(getType(a)))) return TYPE_ARRAY_ARRAY;
7068
if (obj.every(a => getType(a) === TYPE_NUMBER)) return TYPE_ARRAY_NUMBER;
7169
if (obj.every(a => getType(a) === TYPE_STRING)) return TYPE_ARRAY_STRING;
7270
return TYPE_ARRAY;
73-
case '[object Boolean]':
74-
return TYPE_BOOLEAN;
75-
case '[object Null]':
76-
return TYPE_NULL;
77-
default: // '[object Object]':
78-
// Check if it's an expref. If it has, it's been
79-
// tagged with a jmespathType attr of 'Expref';
80-
if (obj.jmespathType === TOK_EXPREF) {
81-
return TYPE_EXPREF;
82-
}
83-
return TYPE_OBJECT;
71+
}
72+
// Check if it's an expref. If it has, it's been
73+
// tagged with a jmespathType attr of 'Expref';
74+
if (obj.jmespathType === TOK_EXPREF) return TYPE_EXPREF;
75+
return TYPE_OBJECT;
8476
}
77+
let type = simpleType(inputObj);
78+
if (type !== TYPE_OBJECT) return type;
79+
// if inputObj is a class, then convert it to its base type via JSON
80+
const obj = JSON.parse(JSON.stringify(inputObj));
81+
type = simpleType(obj);
82+
return type;
8583
}
8684

8785
export function isArrayType(t) {

test/performance/README.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# Measure Performance
2+
3+
## Steps
4+
5+
1. Create a function that tests your performance scenario inside performanceTest.js
6+
e.g. to test sort() we added a function sortPerformance()
7+
2. Update index.js with a path to test this function. e.g. we added app.get('/test/sort', () => {...}) to call sortPerformance()
8+
3. Update tests.html to include a link to your new path
9+
4. run index.js: `node --inspect index.js`
10+
5. open Chrome and navigate to: localhost:3030
11+
6. Open the dev tools and click on the green node.js cube on the top left
12+
7. In the new DevTools window, navigate to the Performance tab and start recording
13+
8. From the browser, click the link for your test
14+
9. When the test is complete, stop recording
15+
10. Look at the "Bottom Up" view to see a table of functions and timings

test/performance/index.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import express from 'express';
2+
import path from 'path';
3+
import { sortPerformance, sortByPerformance } from './performanceTest.js';
4+
5+
const app = express();
6+
7+
app.get('/', (req, res) => {
8+
res.sendFile(path.join(process.cwd(), 'tests.html'));
9+
});
10+
11+
app.get('/test/sort', (req, res) => {
12+
const str = sortPerformance();
13+
res.send(str);
14+
});
15+
16+
app.get('/test/sortby', (req, res) => {
17+
const str = sortByPerformance();
18+
res.send(str);
19+
});
20+
21+
// eslint-disable-next-line no-console
22+
app.listen(3030, 'localhost', () => console.log('Listening on localhost:3030'));
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/*
2+
Copyright 2024 Adobe. All rights reserved.
3+
This file is licensed to you under the Apache License, Version 2.0 (the "License");
4+
you may not use this file except in compliance with the License. You may obtain a copy
5+
of the License at http://www.apache.org/licenses/LICENSE-2.0
6+
7+
Unless required by applicable law or agreed to in writing, software distributed under
8+
the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9+
OF ANY KIND, either express or implied. See the License for the specific language
10+
governing permissions and limitations under the License.
11+
*/
12+
import JsonFormula from '../../src/json-formula.js';
13+
14+
export function sortPerformance() {
15+
const data = [];
16+
for (let i = 0; i < 1000000; i += 1) {
17+
data.push(i.toString());
18+
}
19+
20+
const jsonFormula = new JsonFormula();
21+
const t1 = performance.now();
22+
jsonFormula.search('sort(@)', data);
23+
const t2 = performance.now();
24+
return `Time to sort: ${Math.round(t2 - t1)}ms`;
25+
}
26+
27+
export function sortByPerformance() {
28+
const data = [];
29+
for (let i = 0; i < 1000000; i += 1) {
30+
data.push(i.toString());
31+
}
32+
const jsonFormula = new JsonFormula();
33+
const t1 = performance.now();
34+
jsonFormula.search('sortBy(@, &@)', data);
35+
const t2 = performance.now();
36+
return `Time to sortBy: ${Math.round(t2 - t1)}ms`;
37+
}

test/performance/tests.html

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<html>
2+
<body>
3+
<a href="./test/sort">Test sort</a>
4+
<br>
5+
<br>
6+
<a href="./test/sortBy">Test sortBy</a>
7+
</body>
8+
</html>

0 commit comments

Comments
 (0)