DEV Community


Discussion on: Practical Functional Programming in JavaScript - Control Flow

functional_js profile image
Functional Javascript • Edited

Hey Richard,

That isPromise check should be fast.
I think your bottleneck there will be the recursion idiom.
The iterative idiom is always faster and more robust.
Any recursion can be replaced with a simple loop.
(I never use recursion, it always fails my robustness and performance tests)


However your non-recursive "or" func is slow verses the baseline, and so is its utility, "arrayOr", even when I pass in non-promises (which should make it take the fastest path).

const arrayOr = (fns, x) => {
  const promises = []
  for (let i = 0; i < fns.length; i++) {
    const point = fns[i](x)
    if (isPromise(point)) promises.push(point)
    else if (point) return (promises.length > 0
      ? Promise.all(promises).then(() => true)
      : true)
  return (promises.length > 0
    ? Promise.all(promises).then(res => res.some(x => x))
    : false)

timeInLoop("arrayOr", 1e6, () => arrayOr([() => 1, () => 2, () => 3], 0)) //48.216ms for 1e6


Btw, as a little aside, I perf-compared your isPromise implementation with mine.
Now, my isPromise looks more "proper"; and is actually more robust in my robustness test (not shown here), however yours is magnificently faster, by almost 10x :-) ...

const isPromise = v => v instanceof Promise;

const isPromise2 = x => x && typeof x.then === "function"

const aFalse = [undefined, e => e, {}, { then: {}}, {then: e => e}];
//const aTrue = [new Promise(resolve => { }), new Promise(e => e)];
timeInLoop("isPromise", 1e6, () => isPromise(aFalse)); //93.021ms
timeInLoop("isPromise2", 1e6, () => isPromise2(aFalse)); //10.004ms

prioritized attribute set

So using my "prioritized attribute set" criteria explained in my first post, if I can modify yours enough to be as robust as mine (should be easy to do with very little performance hit) I will swap the slow for the fast.

Thread Thread
richytong profile image
Richard Tong Author

I welcome your contribution. I do not doubt that the current recursive implementation would lose to an iterative implementation. All I request is documentation via issues and then PRs. Also, I'll need to create a benchmarks directory with some examples - I'll do that today.

Forem Open with the Forem app