Reducing Or Whatever

JavaScript performance comparison

Test case created by joshuahiggins

Preparation code


      
      <script>
Benchmark.prototype.setup = function() {
  const victorianSlang = [
      {
          term: 'doing the bear',
          found: true,
          popularity: 108,
      },
      {
          term: 'katterzem',
          found: false,
          popularity: null,
      },
      {
          term: 'bone shaker',
          found: true,
          popularity: 609,
      },
      {
          term: 'smothering a parrot',
          found: false,
          popularity: null,
      },
      {
          term: 'damfino',
          found: true,
          popularity: 232,
      },
      {
          term: 'rain napper',
          found: false,
          popularity: null,
      },
      {
          term: 'donkey’s breakfast',
          found: true,
          popularity: 787,
      },
      {
          term: 'rational costume',
          found: true,
          popularity: 513,
      },
      {
          term: 'mind the grease',
          found: true,
          popularity: 154,
      },
  
  ];

};
</script>

Test runner

Warning! For accurate results, please disable Firebug before running the tests. (Why?)

Java applet disabled.

Testing in CCBot 2.0.0 / Other 0.0.0
Test Ops/sec
not using reduce at all (imperative loop)
let popularitySum = 0;
let itemsFound = 0;
const len = victorianSlang.length;
let item = null;
for (let i = 0; i < len; i++) {
    item = victorianSlang[i];
    if (item.found) {
        popularitySum = item.popularity + popularitySum;
        itemsFound = itemsFound + 1;
    }
}
const averagePopularity = popularitySum / itemsFound;
pending…
easy mode: filter, map, and sum
function isFound(item) {
    return item.found;
};

function getPopularity(item) {
    return item.popularity;
}

function addScores(runningTotal, popularity) {
    return runningTotal + popularity;
}

const foundSlangTerms = victorianSlang.filter(isFound);
const popularityScores = foundSlangTerms.map(getPopularity);
const scoresTotal = popularityScores.reduce(addScores, 0);

const averagePopularity = scoresTotal / popularityScores.length;
pending…
easy mode ii: multiple accumulator values
function isFound(item) {
    return item.found;
};

function getPopularity(item) {
    return item.popularity;
}

function addScores({totalPopularity, itemCount}, popularity) {
    return {
        totalPopularity: totalPopularity + popularity,
        itemCount:       itemCount + 1,
    };
}

const initialInfo    = {totalPopularity: 0, itemCount: 0};
const popularityInfo = victorianSlang.filter(isFound)
    .map(getPopularity)
    .reduce(addScores, initialInfo);

const {totalPopularity, itemCount} = popularityInfo;
const averagePopularity = totalPopularity / itemCount;
pending…
point-free function composition
const filter  = p => a => a.filter(p);
const map     = f => a => a.map(f);
const prop    = k => x => x[k];
const reduce  = r => i => a => a.reduce(r, i);
const compose = (...fns) => (arg) => fns.reduceRight((arg, fn) => fn(arg), arg);

const B1 = f => g => h => x => f(g(x))(h(x));
const sum = reduce((a, i) => a + i)(0);
const length = a => a.length;
const div = a => b => a / b;
const calcPopularity = compose(
    B1(div)(sum)(length),
    map(prop('popularity')),
    filter(prop('found')),
);

const averagePopularity = calcPopularity(victorianSlang);
pending…
single pass with cumulative average calculation
function averageScores({avg, n}, slangTermInfo) {
    if (!slangTermInfo.found) {
        return {avg, n};
    }
    return {
        avg: (slangTermInfo.popularity + n * avg) / (n + 1),
        n:   n + 1,
    };
}

const initialVals       = {avg: 0, n: 0};
const averagePopularity = victorianSlang.reduce(averageScores, initialVals).avg;
pending…
the right answer is always in the comments
const averagePopularity = victorianSlang
  .filter(term => term.found)
  .reduce((avg, term, _, src) => avg + term.popularity/src.length, 0);
pending…

You can edit these tests or add even more tests to this page by appending /edit to the URL.

Compare results of other browsers

0 Comments