PROJET AUTOBLOG


Shaarli - le hollandais volant

Site original : Shaarli - le hollandais volant

⇐ retour index

Create Conway's Game of Life in JavaScript - JavaScript Tutorial | Spicy Yoghurt

vendredi 4 juin 2021 à 21:29

Hi,
I can’t seem to find how to leave a comment on your blog (the comment forms doesn’t show for some reason).

I just found a major way to improuve the performance of your script, that makes it run like 10 times faster, allowing it to run a grid of 200x100 every 50 ms or so.

What your script does is redrawing every single cell on everyloop. This is not required. You can only redraw the cells that have actually changed.
In the begin, about 50% or cells are alive, the rest is dead. As the gave evolves, many more cells are dead, and they remain dead most of the time, not changing theire state between most loops.

Just add a cell.redraw() when changing the .alive to the .nextAlive :

Instead of :

// Apply the new state to the cells
for (let i = 0; i < this.gameObjects.length; i++) {
    this.gameObjects[i].alive = this.gameObjects[i].nextAlive;
}

Do :

if (this.gameObjects[i].alive == this.gameObjects[i].nextAlive) {
    this.gameObjects[i].redraw = false;
} else {
    this.gameObjects[i].redraw = true;
    this.gameObjects[i].alive = this.gameObjects[i].nextAlive;
}

And in the draw() :

Replace :

// Draw a simple square
this.context.fillStyle = this.alive?'#ff8080':'#303030';
this.context.fillRect(this.gridX * Cell.width, this.gridY * Cell.height, Cell.width, Cell.height);

With :

if (this.redraw) {
    // Draw a simple square
    this.context.fillStyle = this.alive?'#ff8080':'#303030';
    this.context.fillRect(this.gridX * Cell.width, this.gridY * Cell.height, Cell.width, Cell.height);
}

This way, you will only redraw the cell (and invoke very costly canvas2D calls) when its needed.

In my instance of your script, I also change every for() loop from :

for (let i=0; i<array.length; i++) { … }

to

for (let i=0, len=array.length; i<len; i++) { … }

This avoids calling a (very) costly array.length() at each loop. Now it’s only called once.

I know nobody cares about performance theses days, but well… I do, I this makes you script much faster. As I said, I can go fullscreen on a 4K screen with 10px cells and still refresh every 50 ms, and on a Intel Integrated Graphics chip.

See it alive here : https://lehollandaisvolant.net/tout/tools/life/


— (permalink)