Skip to content

Commit 939c227

Browse files
committed
Adds the micro-optimizations necessary to push the "no optimizer" interpreter performance beyond json-logic-js.
1 parent f538650 commit 939c227

File tree

6 files changed

+29
-10
lines changed

6 files changed

+29
-10
lines changed

asyncLogic.js

+5-5
Original file line numberDiff line numberDiff line change
@@ -169,11 +169,11 @@ class AsyncLogicEngine {
169169
// END OPTIMIZER BLOCK //
170170

171171
if (Array.isArray(logic)) {
172-
const result = await Promise.all(
173-
logic.map((i) => this.run(i, data, { above }))
174-
)
175-
176-
return result
172+
const res = []
173+
// Note: In the past, it used .map and Promise.all; this can be changed in the future
174+
// if we want it to run concurrently.
175+
for (let i = 0; i < logic.length; i++) res.push(await this.run(logic[i], data, { above }))
176+
return res
177177
}
178178

179179
if (logic && typeof logic === 'object' && Object.keys(logic).length > 0) return this._parse(logic, data, above)

bench/test.js

+12
Original file line numberDiff line numberDiff line change
@@ -71,13 +71,25 @@ for (let j = 0; j < tests.length; j++) {
7171
}
7272
}
7373
console.timeEnd('json-logic-js')
74+
75+
x.disableInterpretedOptimization = true
7476
console.time('le interpreted')
7577
for (let j = 0; j < other.length; j++) {
7678
for (let i = 0; i < 1e5; i++) {
7779
x.run(other[j][0], other[j][1])
7880
}
7981
}
8082
console.timeEnd('le interpreted')
83+
84+
x.disableInterpretedOptimization = false
85+
console.time('le interpreted (optimized)')
86+
for (let j = 0; j < other.length; j++) {
87+
for (let i = 0; i < 1e5; i++) {
88+
x.run(other[j][0], other[j][1])
89+
}
90+
}
91+
console.timeEnd('le interpreted (optimized)')
92+
8193
console.time('le built')
8294
for (let j = 0; j < tests.length; j++) {
8395
for (let i = 0; i < 1e5; i++) {

defaultMethods.js

+6-1
Original file line numberDiff line numberDiff line change
@@ -396,7 +396,12 @@ const defaultMethods = {
396396
not: (value) => Array.isArray(value) ? !value[0] : !value,
397397
'!': (value) => Array.isArray(value) ? !value[0] : !value,
398398
'!!': (value) => Boolean(Array.isArray(value) ? value[0] : value),
399-
cat: (arr) => (typeof arr === 'string' ? arr : arr.join('')),
399+
cat: (arr) => {
400+
if (typeof arr === 'string') return arr
401+
let res = ''
402+
for (let i = 0; i < arr.length; i++) res += arr[i]
403+
return res
404+
},
400405
keys: (obj) => typeof obj === 'object' ? Object.keys(obj) : [],
401406
eachKey: {
402407
traverse: false,

logic.js

+5-1
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,11 @@ class LogicEngine {
142142
}
143143
// END OPTIMIZER BLOCK //
144144

145-
if (Array.isArray(logic)) return logic.map((i) => this.run(i, data, { above }))
145+
if (Array.isArray(logic)) {
146+
const res = []
147+
for (let i = 0; i < logic.length; i++) res.push(this.run(logic[i], data, { above }))
148+
return res
149+
}
146150

147151
if (logic && typeof logic === 'object' && Object.keys(logic).length > 0) return this._parse(logic, data, above)
148152

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "json-logic-engine",
3-
"version": "2.0.1",
3+
"version": "2.0.2",
44
"description": "Construct complex rules with JSON & process them.",
55
"main": "./dist/cjs/index.js",
66
"module": "./dist/esm/index.js",

perf4.js

-2
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,6 @@ console.timeEnd('Unoptimized, Same Object, Static')
3333

3434
console.log('----')
3535

36-
global.gc()
37-
3836
console.time('Optimized, Different Object, Dynamic')
3937
for (let i = 0; i < 1e6; i++) {
4038
optimized.run({ '+': [1, 2, 3, { var: 'a' }] }, { a: i })

0 commit comments

Comments
 (0)