groupBy: reduce vs for vs forOf vs Object.groupBy (v5)

Revision 5 of this benchmark created on


Setup

const keys = ["hello", "world", "wow", "this", "is", "fun"];

const values = [];
for (let i = 0; i < 100_000; i++) {
  values.push([keys[Math.floor(Math.random() * keys.length)], i]);
}

function groupByForOf(iter, fn) {
  const result = {};
  for (const value of iter) {
    const entry = (result[fn(value)] ||= []);
    entry.push(value);
  }
  return result;
}

function groupByFor(iter, fn) {
  const result = {};
  for (let i = 0; i < iter.length; i++) {
    const value = iter[i];
    const entry = (result[fn(value)] ||= []);
    entry.push(value);
  }
  return result
}

function groupByReduce(iter, fn) {
  return iter.reduce((result, value) => {
    const entry = (result[fn(value)] ||= []);
    entry.push(value);
    return result
  }, {});
}

function groupByReduceSpread(iter, fn) {
  return [...iter].reduce((groups, curr) => {
    const key = fn(curr);
    const group = groups[key] ?? [];
    group.push(curr);
    return { ...groups, [key]: group };
  }, {});
}

Test runner

Ready to run.

Testing in
TestOps/sec
reduce
groupByReduce(values, v => v[0])
ready
for of loop
groupByForOf(values, v => v[0])
ready
Object.groupBy
Object.groupBy(values, v => v[0])
ready
for loop
groupByFor(values, v => v[0])
ready
reduce, spreading arguments
groupByReduceSpread(values, v => v[0])
ready

Revisions

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