hmans/miniplex

Destructuring performance

mikecann opened this issue · 3 comments

I was wondering about the performance of destructuring within systems so I decided to run some tests:

import { World } from "miniplex";
import { Entity } from "./miniplex";

const count = 1_000_000;
const iterations = 10;

const world = new World<Entity>();

const positions = world.archetype("position");

const profile = <T>(name: string, fn: () => T) => {
  const before = Date.now();
  const result = fn();
  const after = Date.now();
  console.log(`${name} took ${after - before}ms`);
  return result;
};

const createEntities = () => {
  const entities: Entity[] = [];

  for (let i = 0; i < count; i++)
    entities.push(world.createEntity({ position: { x: 0, y: i, z: 0 }, age: i }));

  return entities;
};

it(`works`, () => {
  profile(`create`, createEntities);

  profile(`destructured`, () => {
    for (let iter = 0; iter < iterations; iter++)
      for (const { position } of positions.entities) position.x += Math.random();
  });

  profile(`not-destructured`, () => {
    for (let iter = 0; iter < iterations; iter++)
      for (const entity of positions.entities) entity.position.x += Math.random();
  });

  profile(`simple for`, () => {
    for (let iter = 0; iter < iterations; iter++)
      for (let i = 0; i < positions.entities.length; i++)
        positions.entities[i]!.position.x += Math.random();
  });
});

Results are:

  console.log
    create took 1794ms

  console.log
    destructured took 2363ms

  console.log
    not-destructured took 1502ms

  console.log
    simple for took 1473ms

So it looks like destructuring has quite a large impact.. having said that tho there could be some CPU vectorization / JIT'ing going on here that might cause oddness.

hmans commented

Turning around the order of execution yielded the following results, making destructured access appear significantly faster:

  console.log
    create took 603ms

  console.log
    not-destructured took 1196ms

  console.log
    destructured took 756ms

  console.log
    simple for took 751ms

As far as I know, the JavaScript runtime is pretty efficient at inlining destructuring statements. I assume what you're seeing here is the effect of caching.

hmans commented

The difference evens out with a lower number of entities and a higher number of iterations:

  console.log
    simple for took 752ms

  console.log
    not-destructured took 724ms

  console.log
    destructured took 719ms

Ye okay.. I was seeing odd numbers when I didnt use Math.random() too.

I was hoping it would be smart about the destructuring its good that these tests have been done tho :)