performance tips for computations on an ESP32

• This is my final code (for an original Espruino, with a 16x16 Neopixel LED matrix wired to pin B15) - just for the case that you want to play with it:

``````  let Neopixel = require("neopixel");

let rounded = Math.round;
let clamped = E.clip;
let max     = Math.max;

let DisplaySize = 16*16;
let Display     = new Uint8ClampedArray(DisplaySize*3);

let PixelOffset = new Int16Array(256);
for (let i = 0; i < 16; i++) {
for (let j = 0; j < 16; j++) {
let Index = i*16 + j;
if (i % 2 === 0) {
PixelOffset[Index] = Index*3;
} else {
PixelOffset[Index] = (i*16 + 15 - j)*3;
}
}
}

let normalized = new Uint8ClampedArray(16*16);
for (let i = 0; i < 256; i++) {
normalized[i] = (
i === 0
? 0
: rounded(1 + 256/4*(i/256)*(i/256))
);
}

let TemperatureMap = new Uint8ClampedArray(DisplaySize);
for (let i = 0; i < 256; i++) {
TemperatureMap[i] = 0;
}

let ColorMap = new Array(16);
for (let i = 0; i < 16; i++) {
ColorMap[i] = E.HSBtoRGB(i/16, 1, 1, true);
}

/**** computeDiffusion ****/

function computeDiffusion () {
let i = 0, j = 0, k = 0;
for (i = 15; i > 0; i--) {             // intensity diffusion for upper rows
k = i*16;
TemperatureMap[k] = rounded((
6*TemperatureMap[k] + 2*TemperatureMap[k-16] + TemperatureMap[k-15]
)/9);

for (j = 1; j < 15; j++) {
k++;
TemperatureMap[k] = rounded((
6*TemperatureMap[k] +
TemperatureMap[k-17] + 2*TemperatureMap[k-16] + TemperatureMap[k-15]
)/10);
}

k++;
TemperatureMap[k] = rounded((
6*TemperatureMap[k] + TemperatureMap[k-17] + 2*TemperatureMap[k-16]
)/9);
}
}

/**** computeHeating ****/

let HeatX     = rounded(16*Math.random());         // where to insert new heat
let HeatCount = rounded(12*Math.random());           // how long to heat there

function computeHeating () {
HeatCount -= 1;
if (HeatCount < 0) {                    // heat around HeatX, cool elsewhere
HeatX     = rounded(16*Math.random());
HeatCount = rounded(12*Math.random());
}

let i, l = HeatX-4;
for (i = 0/*, l = HeatX-4*/; i < l; i++) {
TemperatureMap[i] = clamped(TemperatureMap[i] - 8, 0,255);
}
i = HeatX-4;
i++; if (i >= 0) { TemperatureMap[i] = clamped(TemperatureMap[i] + 1, 0,255); }
i++; if (i >= 0) { TemperatureMap[i] = clamped(TemperatureMap[i] + 3, 0,255); }
i++; if (i >= 0) { TemperatureMap[i] = clamped(TemperatureMap[i] + 4, 0,255); }
i++;               TemperatureMap[i] = clamped(TemperatureMap[i] + 5, 0,255);
i++; if (i < 16) { TemperatureMap[i] = clamped(TemperatureMap[i] + 4, 0,255); }
i++; if (i < 16) { TemperatureMap[i] = clamped(TemperatureMap[i] + 3, 0,255); }
i++; if (i < 16) { TemperatureMap[i] = clamped(TemperatureMap[i] + 1, 0,255); }
i++;
for (i = i; i < 16; i++) {
TemperatureMap[i] = clamped(TemperatureMap[i] - 8, 0,255);
}
}

/**** prepare display ****/

let normalizedRGB = new Uint8ClampedArray(3);

function prepareDisplay () { "compiled";
for (let i = 0; i < 16; i++) {                                   // row-wise
let RowStart = i*16; let RowEnd = RowStart + 15;
let k = RowStart;
for (let j = 0/*, k = RowStart*/; j < 16; j++/*, k++*/) {   // column-wise
let RGB         = ColorMap[j];
let Temperature = TemperatureMap[k];
if (Temperature < 16) {
Temperature = 0;
} else {
Temperature = max(48,Temperature)/256;
}

normalizedRGB[0] = normalized[rounded(RGB[1]*Temperature)];­
normalizedRGB[1] = normalized[rounded(RGB[0]*Temperature)];­
normalizedRGB[2] = normalized[rounded(RGB[2]*Temperature)];­

Display.set(normalizedRGB, PixelOffset[k]);

k++;
}
}
}

/**** handleNextFrame ****/

function handleNextFrame () {
computeDiffusion();
computeHeating();
prepareDisplay();

/**** show display ****/

Neopixel.write(B15,Display);

/**** wait for next frame and proceed ****/

setTimeout(handleNextFrame,10);
}

/**** start automatically ****/

setTimeout(handleNextFrame,1000);       // give Espruino some time to start up
``````