# How to improve performance: multiple array operations on pixels

**URL:** <https://discourse.processing.org/t/how-to-improve-performance-multiple-array-operations-on-pixels/41078>\
**Category:** Coding Questions\
**Created:** [February 27, 2023, 8:48am UTC](https://discourse.processing.org/t/how-to-improve-performance-multiple-array-operations-on-pixels/41078 "2023-02-27T08:48:21Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![flodeux](https://avatars.discourse-cdn.com/v4/letter/f/3e96dc/32.png) [@flodeux](https://discourse.processing.org/u/flodeux)\
**Post date:** [February 27, 2023, 8:48am UTC](https://discourse.processing.org/t/how-to-improve-performance-multiple-array-operations-on-pixels/41078/1 "2023-02-27T08:48:21Z")

</div>

Hi all 🙂  
I’m back to processing. I was using this tool when i was student 10 years ago, and its really pleasure to re-use it !

I’m triyng to use Kinect to generate design and im working to calculate pixels data evolutions, that mean i need to use long multiple array treatment… This work make slowdown my screenview… Anyone know a Library or a tips to improve performance ?  
Thank you !! 🙂

---

<div class="post-metadata">

**Author:** ![josephh](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/josephh/32/210_2.png) [@josephh](https://discourse.processing.org/u/josephh)\
**Post date:** [February 27, 2023, 9:33am UTC](https://discourse.processing.org/t/how-to-improve-performance-multiple-array-operations-on-pixels/41078/2 "2023-02-27T09:33:14Z")

</div>

Hi @flodeux,

Welcome back! 😉

> [@flodeux](#):
>
> i need to use long multiple array treatment… This work make slowdown my screenview… Anyone know a Library or a tips to improve performance ?

Most of the time it’s done using [Multithreading](https://en.wikipedia.org/wiki/Multithreading_(computer_architecture)) which works by breaking your problem into smaller ones and solving them in parallel in different threads.

I don’t know the internals of how your algorithm works but you can also find ways to improve efficiency with programming / algorithmic tricks. (choosing the right data structures, avoid cache misses and useless memory allocations…)

---

<div class="post-metadata">

**Author:** ![flodeux](https://avatars.discourse-cdn.com/v4/letter/f/3e96dc/32.png) [@flodeux](https://discourse.processing.org/u/flodeux)\
**Post date:** [February 27, 2023, 11:20am UTC](https://discourse.processing.org/t/how-to-improve-performance-multiple-array-operations-on-pixels/41078/3 "2023-02-27T11:20:50Z")

</div>

Hi, thank you for the answer.  
That mean i need to try using the “thread()” class ? ([thread() / Reference / Processing.org](https://processing.org/reference/thread_.html))  
I will try that, im using

```auto
  for (int y=0; y<elmt.height; y++){
    for (int x =0; x<elmt.width; x++){..}}

```

I’ll may try something like

`for (int y=0; y<elmt.height; y++){thread("threadX");}`

I hope i can have a way to pass argument to the thread call.  
It is something like that, you was thinking about ?

Thank you very much 😉

.Flodeux.

---

<div class="post-metadata">

**Author:** ![josephh](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/josephh/32/210_2.png) [@josephh](https://discourse.processing.org/u/josephh)\
**Post date:** [March 4, 2023, 6:18pm UTC](https://discourse.processing.org/t/how-to-improve-performance-multiple-array-operations-on-pixels/41078/4 "2023-03-04T18:18:15Z")

</div>

Hi @flodeux,

Sorry for the late answer 😉

> [@flodeux](#):
>
> That mean i need to try using the “thread()” class ?

The Processing `thread()` function is a wrapper for easily creating a `Thread` instance that launches a method defined earlier. (see the [actual code here](https://github.com/processing/processing4/blob/main/core/src/processing/core/PApplet.java#L3507)).

What you need to do is to break your image into square tiles, one for each thread, do the computation of each specific tile and then wait for all the threads to finish.

This is an example by extending the `Thread` class and assigning a random color for each time:

```processing
class TileThread extends Thread {
  int x, y, w, h;
  color randomColor;

  TileThread(int x, int y, int w, int h) {
    this.x = x;
    this.y = y;
    this.w = w;
    this.h = h;

    randomColor = color(random(255), random(255), random(255));
  }

  void run() {
    for (int i = x; i < x + w; i++) {
      for (int j = y; j < y + h; j++) {
        int loc = i + width * j;
        pixels[loc] = randomColor;
      }
    }
  }
}

int nTiles = 5;

void setup() {
  size(500, 500);
}

void draw() {
  int tileSizeX = width / nTiles;
  int tileSizeY = height / nTiles;
  ArrayList<Thread> tileThreads = new ArrayList();
  
  loadPixels();
  
  // Create one thread for each square tile (like a grid)
  for (int i = 0; i < nTiles; i++) {
    int x = i * tileSizeX;
    for (int j = 0; j < nTiles; j++) {
      int y = j * tileSizeY;
      
      Thread thread = new TileThread(x, y, tileSizeX, tileSizeY);
      thread.run();
      tileThreads.add(thread);
    }
  }
  
  // Wait for all the threads to finish
  for (Thread thread : tileThreads) {
    try {
      thread.join();
    } catch (InterruptedException e) {
      println(e);
    }
  }

  updatePixels();
}

```

(this works when the canvas size is divisible by `nTiles` but you can support non square tiles)  
(be careful not to modify the same tiles from two different threads leading to a [race condition](https://en.wikipedia.org/wiki/Race_condition))

---

<div class="post-metadata">

**Author:** ![flodeux](https://avatars.discourse-cdn.com/v4/letter/f/3e96dc/32.png) [@flodeux](https://discourse.processing.org/u/flodeux)\
**Post date:** [March 6, 2023, 8:29am UTC](https://discourse.processing.org/t/how-to-improve-performance-multiple-array-operations-on-pixels/41078/5 "2023-03-06T08:29:32Z")

</div>

Hi Josehh! Thank you for your answer 🙂  
Yes i was trying with Thread, but it was impossible to send var to the Thread, maybe this way would be better for me, I’ll try and decompose this to understand, thank you very munch !! 🙂

---

<div class="post-metadata">

**Author:** ![mnse](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/mnse/32/16520_2.png) [@mnse](https://discourse.processing.org/u/mnse)\
**Post date:** [March 7, 2023, 12:12pm UTC](https://discourse.processing.org/t/how-to-improve-performance-multiple-array-operations-on-pixels/41078/6 "2023-03-07T12:12:00Z")

</div>

Hi @flodeux,

if you still want more performance and ready for new experiences considering the usage of shaders  
… as a future step … 🙂

Cheers  
— mnse

###### processing java version

```auto
PShader myshader;

void setup() {
  size(400, 400, P2D);
  myshader=new PShader(g.parent, vertexShader, fragmentShader);
}

void draw() {
  int tileSizeX = width/8;
  int tileSizeY = height/8;

  for (int y=0; y<=height; y+=tileSizeY) {
    for (int x=0; x<=width; x+=tileSizeX) {
      myshader.set("color", random(1), random(1), random(1));
      shader(myshader);
      rect(x, y, tileSizeX, tileSizeY);
    }
  }
}

String[] vertexShader = {"""
#version 330 core
precision highp float;
uniform mat4 transformMatrix;
layout (location = 0) in vec4 position;

void main()
{
  gl_Position = transformMatrix * position;
}
"""};

String[] fragmentShader = {"""
#version 330 core
precision highp float;
uniform vec3 color;
out vec4 glFragColor;

void main()
{
  glFragColor = vec4(color, 1.0);
}
"""};

```

###### converted to p5 to visualize:
https://editor.p5js.org/mnse_forum/full/JTgblpRXI

PS:

###### p5 code:

```auto
let myshader;

function setup() {
  createCanvas(400, 400, WEBGL);
  noStroke();
  myshader = createShader(vertexShader, fragmentShader);
}

function draw() {    
  translate(-width/2,-height/2);
  var tileSizeX = width / 8.;
  var tileSizeY = height / 8.;
  for (var y = 0; y <= height; y += tileSizeY) {
    for (var x = 0; x <= width; x += tileSizeX) {
      myshader.setUniform("color", [
        Math.random(),
        Math.random(),
        Math.random(),
      ]);
      shader(myshader);
      rect(x, y, tileSizeX, tileSizeY);
    }
  }
}

const vertexShader = `
precision highp float;
uniform mat4 uProjectionMatrix;
uniform mat4 uModelViewMatrix;
uniform mat4 uModelMatrix;

attribute vec3 aPosition;

void main() {
  vec4 positionVec4 = vec4(aPosition, 1.0);
  positionVec4.xy = positionVec4.xy * 2.0 - 1.0;
  gl_Position = uProjectionMatrix * uModelViewMatrix * positionVec4;  
}
`;

const fragmentShader = `
precision highp float;
uniform vec3 color;

void main()
{
  gl_FragColor = vec4(color, 1.0);
}
`;

```
