tl;dr: Calling bind on a function is expensive because each call creates a net new function. Memoize bindings outside of loops and just call the bound functions inside the loops.

sum.bind(this) === sum.bind(this)
// false, which shows that the bound functions are different even when called with the same parameters, which makes sense.
function sum() {
  let total = 0;

  for (let i = 0; i < this.count; ++i) {
    total += i;
  }

  return total;
}

const t0 = performance.now();
for (let i = 0; i < 1e3; ++i) {
  const fn = sum.bind({ count: 1e3 });
  fn();
}
const t1 = performance.now();
console.log(".bind every time", t1 - t0, "ms");

const t2 = performance.now();
const fn = sum.bind({ count: 1e3 }); // memoized outside the loop
for (let i = 0; i < 1e3; ++i) {
  fn();
}
const t3 = performance.now();
console.log(".bind once", t3 - t2, "ms");
.bind every time 3.300000011920929 ms
.bind once 1.800000011920929 ms

Binding once outside of the loop, essentially memoizing the bound function, is faster than binding over and over again at each step of the loop.