for each vs reduce vs for loop

Benchmark created on


Setup

// Generate a random integer between 1 and 10000
const min = 1;
const max = 10000;
const randomNumber = () => Math.floor(Math.random() * (max - min + 1)) + min;

function generateRandomString(length) {
  const charset = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()_+-=[]{}|;:,.<>?";
  let randomString = "";

  for (let i = 0; i < length; i++) {
    const randomIndex = Math.floor(Math.random() * charset.length);
    randomString += charset.charAt(randomIndex);
  }

  return randomString;
}

const todosFromServer = []

for (let i = 0; i < max; i++) {
  todosFromServer[i] = { userId: randomNumber(), value: generateRandomString(100) }
}


// -----

function forEachFn(todos) {
  const todosForUserMap = {}

  todos.forEach(todo => {
    if (todosForUserMap[todo.userId]) {
      todosForUserMap[todo.userId].push(todo)
    } else {
      todosForUserMap[todo.userId] = [todo]
    }
  })

  return todosForUserMap
}


// ---

function reduceFn(todos) {
  const todosForUserMap = todos.reduce((accumulator, todo) => {
    if (accumulator[todo.userId]) accumulator[todo.userId].push(todo)
    if (!accumulator[todo.userId]) accumulator[todo.userId] = [todo]
    return accumulator
  }, {})

  return todosForUserMap
}

// ---

function forLoopFn(todos) {
  const todosForUserMap = {}

  for (let i = 0; i < todos.length; i++) {
    const todo = todos[i]
    if (todosForUserMap[todo.userId]) {
      todosForUserMap[todo.userId].push(todo)
    } else {
      todosForUserMap[todo.userId] = [todo]
    }
  }

  return todosForUserMap
}

Test runner

Ready to run.

Testing in
TestOps/sec
forEachFn
forEachFn(todosFromServer)
ready
reduceFn
reduceFn(todosFromServer)
ready
forLoopFn
forLoopFn(todosFromServer)
ready

Revisions

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