Skip to content

Commit 8925471

Browse files
AntonPiepermarcbachmann
authored andcommitted
perf(operators): specialize accuPush comprehension loops
1 parent f3b7ff2 commit 8925471

1 file changed

Lines changed: 32 additions & 0 deletions

File tree

lib/operators.js

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,10 @@ function runComprehension(items, args, ev, ctx) {
388388
if (!isArray(items)) items = toIterable(ev, args, items)
389389
const accu = ev.eval(args.init, (ctx = args.iterCtx.reuse(ctx)))
390390
ctx.accuValue = accu
391+
if (args.step.op === 'accuPush') {
392+
if (ctx === args.iterCtx) return iterateLoopAccuPush(ev, ctx, args, items, accu, 0)
393+
return continueLoopAccuPush(ev, ctx, args, items, accu, 0)
394+
}
391395
if (ctx === args.iterCtx) return iterateLoop(ev, ctx, args, items, accu, 0)
392396
return continueLoop(ev, ctx, args, items, accu, 0)
393397
}
@@ -418,6 +422,34 @@ async function continueLoop(ev, ctx, args, items, accu, i) {
418422
return args.result(accu)
419423
}
420424

425+
function iterateLoopAccuPush(ev, ctx, args, items, accu, i) {
426+
const condition = args.condition
427+
const transform = args.step.args
428+
const len = items.length
429+
while (i < len) {
430+
if (condition && !condition(accu)) break
431+
const value = ev.eval(transform, ctx.setIterValue(items[i++], ev))
432+
if (value instanceof Promise) return continueLoopAccuPush(ev, ctx, args, items, accu, i, value)
433+
accu.push(value)
434+
}
435+
return args.result(accu)
436+
}
437+
438+
async function continueLoopAccuPush(ev, ctx, args, items, accu, i, value) {
439+
if (ctx === args.iterCtx) ctx.async = true
440+
const condition = args.condition
441+
const transform = args.step.args
442+
const len = items.length
443+
444+
if (value !== undefined) accu.push(await value)
445+
while (i < len) {
446+
if (condition && !condition(accu)) return args.result(accu)
447+
value = ev.eval(transform, ctx.setIterValue(items[i++], ev))
448+
accu.push(value instanceof Promise ? await value : value)
449+
}
450+
return args.result(accu)
451+
}
452+
421453
function iterateQuantifier(ev, ctx, args, items, accu, i, error, stp) {
422454
const condition = args.condition
423455
const step = args.step

0 commit comments

Comments
 (0)