0

I have the following function:

ColorPalette._processPaletteImageData = function() {
    const paletteImage = this._bmp();
    const source = this._source;
    if (paletteImage) {
        const _colorPicker = (_n) => {
            const pX = source.offsetX + (_n % 8) * 12 + 6;
            const pY = source.offsetY + Math.floor(_n / 8) * 12 + 6;
            return paletteImage.getPixel(pX, pY);
        };
        const _toRgba = (_o) => {return [_o.r, _o.g, _o.b, _o.a]};
        const dataDivisions = source.dataDivisions;
        const splits = (dataDivisions.length - 1);
        let tally = 0;
        for (let i = 0; i <= splits; i++) {
            this._data[i] = {};
            const colors = (dataDivisions[i] - 1);
            for (let j = 0; j <= colors; j++) {
                const position = tally + j;
                const hex = _colorPicker(position);
                const color = tinycolor(hex);
                const rgba = _toRgba(color.toRgb());
                const score = Utils.computeColorScore(rgba);
                const [colorName, shade] = Utils.hexToColorName(hex).split(DIVISION);
                const inverse = Utils.invertColor(hex, false);
                const complement = color.complement().toHexString();
                this._data[i][colorName] = {
                    "hex": hex,
                    "compliment": complement,
                    "inverse": inverse,
                    "rgba": rgba,
                    "score": score,
                    "shade": shade,
                };
            };
            tally += colors + 1;
        };
    };
};

There are two for statements in the aforementioned code:

  1. for (let i = 0; i <= splits; i++)
  2. for (let j = 0; j <= colors; j++)

How would I rewrite the function so that the For statements look like:

  1. for (let i = splits; i >= 0; i--)
  2. for (let j = colors; j >= 0; j--)
jonrsharpe
  • 115,751
  • 26
  • 228
  • 437
Aporokizzu
  • 13
  • 3
  • 2
    Is your code currently working as expected? Why do you think that inverting loops order will improve performance? – Ernesto Stifano Aug 09 '21 at 12:10
  • Additionally, to help you optimize your code it would be helpful to understand what are you trying to do in the first place. – Ernesto Stifano Aug 09 '21 at 12:13
  • @ErnestoStifano: Presumably because, when JITing to x86 machine code, it can compile to `dec reg / jge` instead of `inc reg` / `cmp reg,reg` / `jle`, saving an instruction (and on non-AMD CPUs, a uop for the front-end) and maybe freeing up a register that doesn't need to hold a loop bound. IDK whether current JS JIT compilers will make nicer loops for less idiomatic source or not. However, if using `i` or `j` to index memory, slightly worse hardware prefetch for looping in order of decreasing addresses could be a bigger factor. – Peter Cordes Aug 09 '21 at 12:15
  • (It's obviously not worth making the loop body more complicated just to enable different loop control, that would defeat any tiny savings, so if there's any inter-iteration dependency or reason to loop in forward order, just do that.) – Peter Cordes Aug 09 '21 at 12:15
  • @PeterCordes thank you for pointing that out, it is very interesting. I particularly agree with your latest comment. Especially if we consider modern ECMAScript engines which optimizations are heavily dynamic and not necessarily involve a direct JIT compilation step to machine code. Any code executed inside the loop will most likely impact performance in a much exaggerated way than the loop structure itself. – Ernesto Stifano Aug 09 '21 at 13:52

0 Answers0