# Pixels array p5.js vs java improving speed

**URL:** <https://discourse.processing.org/t/pixels-array-p5-js-vs-java-improving-speed/38623>\
**Category:** Coding Questions\
**Created:** [September 3, 2022, 12:56am UTC](https://discourse.processing.org/t/pixels-array-p5-js-vs-java-improving-speed/38623 "2022-09-03T00:56:05Z")\
**Posts on this page:** 15\
**Page:** 1

<div class="post-metadata">

**Author:** ![Sunt](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/sunt/32/16827_2.png) [@Sunt](https://discourse.processing.org/u/Sunt)\
**Post date:** [September 3, 2022, 12:56am UTC](https://discourse.processing.org/t/pixels-array-p5-js-vs-java-improving-speed/38623/1 "2022-09-03T00:56:06Z")

</div>

Hi. I translated a java to a p5.js sketch.  
The p5.js pixels array takes 4 times more values and I believe that is why it the sketch runs far more slowly. The java sketch runs faster as the gif image below. The p5.js runs terribly slow as you can see [here in the web editor](https://editor.p5js.org/sunt/sketches/nszhjq3DR). Is there a way (maybe through bit shifting) to improve the speed?

java:

```auto
int k[] = new int[128];
int[] a;
float u, v, r = 42, g = 84, b = 128;
int w = 300, p = 0;

void setup() {
  size(300, 300);
  a = new int[w * w];
  for (int x = 0; x < w; x++) {
    for (int y = 0; y < w; y++) {
      a[x + y * w] = int((b + (b * sin(x / 32.0)) +
        (b + (b * cos(y / 32.0))) +
        (b + (b * sin(sqrt((x * x + y * y)) / 32.0)))) / 4);
    }
  }
}

void draw() {
  p++;
  for (int i = 0; i < b; i++) {
    u = sin(i * 0.12);
    v = sin(i * PI / 50 + 0.79);
    k[i] = color(r + u * b, g + v * b, b + u * b);
  }
  loadPixels();
  for (int i = 0; i < w * w; i++) {
    pixels[i] = k[(a[i] + p) & 127];
  }
  updatePixels();
}

```

p5.js:

```auto
let a = [];
let k = [];
let u, v, r = 42, g = 84, b = 128, p = 0, s = 32;

function setup() {
  createCanvas((w = 300), w);
  pixelDensity(1);
  for (let x = 0; x < w; x ++) {
    for (let y = 0; y < 4 * w; y ++) {
      a[x * 4 + y * 4* w] = int((b + b * sin(x / 32.0) +
      (b + b * cos(y / s)) +
      (b + b * sin(sqrt(x * x + y * y) / s))) / 4);
    }
  }
}

function draw() {
  p++;
  for (i = 0; i < 128; i++) {
    u = sin(i * 0.12);
    v = sin(i * PI / 50 + 0.79);
    k[i] = color(r + u * b, g + v * b, b + u * b);
  }
  loadPixels();
  for (let i = 0; i < 4 * w * w; i += 4) {
    c = k[(a[i] + p) & 127];
    pixels[i] = red(c);
    pixels[i + 1] = green(c);
    pixels[i + 2] = blue(c);
    pixels[i + 3] = alpha(c);
  }
  updatePixels();
}

```

![plasma](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/3X/e/4/e4a67718c33e277cf437e5a2fddbc1a63fd237fe.gif)

---

<div class="post-metadata">

**Author:** ![GoToLoop](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/gotoloop/32/86_2.png) [@GoToLoop](https://discourse.processing.org/u/GoToLoop)\
**Post date:** [September 3, 2022, 2:56pm UTC](https://discourse.processing.org/t/pixels-array-p5-js-vs-java-improving-speed/38623/2 "2022-09-03T14:56:25Z")

</div>

> [@Sunt](#):
>
> I translated a Java to a p5.js sketch.

If your aim was just to make it run online just know your sketch is totally convertible to [Processing.js](https://gotoloop.github.io/processing-js.github.io/):

https://OpenProcessing.org/sketch/1637958/embed/
## index.html:

```auto
<script defer src=https://Unpkg.com/processing-js></script>
<canvas data-src=Trig_Pixel_Colors.pde></canvas>

```

As you can see from the embedded [`<iframe>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe) above I’ve made many changes to your Java sketch.

Most important 1 was moving the _K[]_ array initialization to **setup()**.

After all, nothing in the _K[]_ array changes after it’s filled w/ colors the 1st time, just like _A[]_.

> [@Sunt](#):
>
> The p5.js pixels array takes 4 times more values…

> [@Sunt](#):
>
> The p5.js runs terribly slow…

While Java Mode uses a 32bit integer value to represent an [aRGB](https://processing.org/reference/color_datatype.html) color for its [_pixels[]_](https://processing.org/reference/pixels.html) array, p5js version goes w/ an Uint8ClampedArray container which requires 4 elements to represent an [RGBa](https://p5js.org/reference/#/p5/pixels) value:

> **[Uint8ClampedArray - JavaScript | MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8ClampedArray)**
>
> The Uint8ClampedArray typed array represents an array of 8-bit unsigned integers clamped to 0–255. The contents are initialized to 0 unless initialization data is explicitly provided. Once established, you can reference elements in the array using...

However there’s a workaround to access p5js’ _pixels[]_ as a 32bit value!

We simply create a new 32bit typed array, either [Int32Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Int32Array) or [Uint32Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint32Array), and pass the _pixels[]_'s Uint8ClampedArray::[_buffer_](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/buffer) to its constructor:  
`pix32 = new Uint32Array(pixels.buffer);`

This way we get a view over the original [Uint8ClampedArray](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8ClampedArray) container, where any changes made to 1 reflect on the other.

The only trap about it is that typed arrays store their values according to a computer’s endianness, which for almost all personal devices is little-endian:

> **[Endianness - Glossary | MDN](https://developer.mozilla.org/en-US/docs/Glossary/Endianness)**
>
> Endian and endianness (or "byte-order") describe how computers organize the bytes that make up numbers.

So we need to invert the byte-order when we’re converting a sequence of RGBa 8bit values to a 32bit unified value, resulting in an aBGR order!

Another obstacle is that p5js’ [**color()**](https://p5js.org/reference/#/p5/color) returns a [p5.Color](https://p5js.org/reference/#/p5.Color) object rather than a 32bit value like Processing’s.

Among the many [p5.Color](https://p5js.org/reference/#/p5.Color) undocumented properties is _levels[]_, which stores an RGBa representation as a 4-_length_ array:  
`{ levels: rgbaArray } = color(R + u, G + v, B + u),`

The line above relies on an [object destructuring assignment](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment#object_destructuring) in order to unpack the _levels[]_ property from the [p5.Color](https://p5js.org/reference/#/p5.Color) object and then rename it to _rgbaArray[]_.

Next step now is to convert that 4-_length_ array to an aBGR unified value.

For that I’ve chosen method Array::**reduce()**:

> **[Array.prototype.reduce() - JavaScript | MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce)**
>
> The reduce() method of Array instances executes a user-supplied "reducer" callback function on each element of the array, in order, passing in the return value from the calculation on the preceding element. The final result of running the reducer...

`abgrValue = rgbaArray.reduce(RGBa_Arr_to_aBGR_32bit_Val, 0);`

```javascript
function RGBa_Arr_to_aBGR_32bit_Val(acc, val, idx) {
  return acc | val << idx * 0o10;
}

```

Here’s the complete p5js sketch running online w/ same performance as Processing’s:

https://OpenProcessing.org/sketch/1637961/embed/
## index.html:

```auto
<script async src=https://cdn.JsDelivr.net/npm/p5></script>
<script defer src=sketch.js></script>

```

Extra links about other JS syntaxes I’ve used on the p5js flavor:

- Math.[**hypot()**](https://developer.mozilla.org/en-%5BUS/docs/Web/JavaScript/Reference/Global_Objects/Math/hypot)
- [Left shift operator (\<\<)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Left_shift)
- [Bitwise XOR assignment (^=)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_XOR_assignment)
- Array::[**reverse()**](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reverse)

---

<div class="post-metadata">

**Author:** ![quark](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/quark/32/26_2.png) [@quark](https://discourse.processing.org/u/quark)\
**Post date:** [September 3, 2022, 4:36pm UTC](https://discourse.processing.org/t/pixels-array-p5-js-vs-java-improving-speed/38623/3 "2022-09-03T16:36:55Z")

</div>

One fix is to calculate the `k` array just once in setup rather than every frame.

```auto
let a = [];
let k = [];
let u, v, r = 42, g = 84, b = 128, p = 0, s = 32;

function setup() {
  createCanvas((w = 300), w);
  pixelDensity(1);
  for (let x = 0; x < w; x ++) {
    for (let y = 0; y < 4 * w; y ++) {
      a[x * 4 + y * 4* w] = int((b + b * sin(x / 32.0) +
        (b + b * cos(y / s)) +
        (b + b * sin(sqrt(x * x + y * y) / s))) / 4);
    }
  }
  for (i = 0; i < 128; i++) {
    u = sin(i * 0.12);
    v = sin(i * PI / 50 + 0.79);
    k[i] = color(r + u * b, g + v * b, b + u * b);
  }
}

function draw() {
  p++;
  loadPixels();
  for (let i = 0; i < 4 * w * w; i += 4) {
    c = k[(a[i] + p) & 127];
    pixels[i] = red(c);
    pixels[i + 1] = green(c);
    pixels[i + 2] = blue(c);
    pixels[i + 3] = alpha(c);
  }
  updatePixels();
}

```

---

<div class="post-metadata">

**Author:** ![quark](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/quark/32/26_2.png) [@quark](https://discourse.processing.org/u/quark)\
**Post date:** [September 3, 2022, 5:54pm UTC](https://discourse.processing.org/t/pixels-array-p5-js-vs-java-improving-speed/38623/4 "2022-09-03T17:54:21Z")

</div>

I have made the following changes

1. calculate the k array in setup rather than every frame
2. using the array.length rather than calculate the number of pixels in every loop iteration.
3. the `k` array does not use the alpha channel so set alpha to 255 (opaque) directly
4. get the rgb channel values directly from the pixel color rather that via the graphics objectt

The last one should avoid p5.js doing a lot of internal color mode calcs, although I am not sure.

```auto
let a = [];
let k = [];
let u, v, r = 42, g = 84, b = 128, p = 0, s = 32;

function setup() {
  createCanvas((w = 300), w);
  pixelDensity(1);
  for (let x = 0; x < w; x ++) {
    for (let y = 0; y < 4 * w; y ++) {
      a[x * 4 + y * 4* w] = int((b + b * sin(x / 32.0) +
        (b + b * cos(y / s)) +
        (b + b * sin(sqrt(x * x + y * y) / s))) / 4);
    }
  }
  for (i = 0; i < 128; i++) {
    u = sin(i * 0.12);
    v = sin(i * PI / 50 + 0.79);
    k[i] = color(r + u * b, g + v * b, b + u * b);
  }
}

function draw() {
  p++;
  loadPixels();
  for (let i = 0; i < pixels.length; i += 4) {
    c = k[(a[i] + p) & 127];
    pixels[i] = c._getRed();
    pixels[i + 1] = c._getGreen();
    pixels[i + 2] = c._getBlue();
    pixels[i + 3] = 255;
  }
  updatePixels();
}

```

You would need to do some bench marking to see if any improvement is significant 😄

---

<div class="post-metadata">

**Author:** ![Sunt](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/sunt/32/16827_2.png) [@Sunt](https://discourse.processing.org/u/Sunt)\
**Post date:** [September 3, 2022, 7:21pm UTC](https://discourse.processing.org/t/pixels-array-p5-js-vs-java-improving-speed/38623/5 "2022-09-03T19:21:24Z")

</div>

Thank you so much for the detailed info and relevant links. I’m going to study these carefully. The speed is excellent now!

---

<div class="post-metadata">

**Author:** ![Sunt](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/sunt/32/16827_2.png) [@Sunt](https://discourse.processing.org/u/Sunt)\
**Post date:** [September 3, 2022, 8:15pm UTC](https://discourse.processing.org/t/pixels-array-p5-js-vs-java-improving-speed/38623/6 "2022-09-03T20:15:37Z")

</div>

Thank you very much. The changes including the last one, which I tested maintaining the k array in draw, but using the rgb channel values directly from the pixel color improves the speed a lot. When using an 800/800 canvas, the original sketch nearly stops, but when using the values directly, the sketch still runs fluidly. So that’s a big win. My goal was trying to make a processing’s tweet of it, but that is not going to happen. Still far too much characters 😒

> a=k=,r=42,g=84,b=128,u=v=p=0,s=32,setup=e=\>{createCanvas(w=400,w),pixelDensity(1);for(let e=0;e\<w;e++)for(let i=0;i\<4_w;i++)a[4_e+4_i_w]=int((b+b_sin(e/32)+(b+b_cos(i/s))+(b+b_sin(sqrt(e_e+i_i)/s)))/4);for(i=0;i\<128;i++)u=sin(.12_i),v=sin(i_PI/50+.79),k[i]=color(r+u_b,g+v_b,b+u_b)},draw=e=\>{p++,loadPixels();for(let e=0;e\<pixels.length;e+=4)c=k[a[e]+p&127],pixels[e]=c.\_getRed(),pixels[e+1]=c.\_getGreen(),pixels[e+2]=c.\_getBlue(),pixels[e+3]=255;updatePixels()};//#つぶやきProcessing

---

<div class="post-metadata">

**Author:** ![quark](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/quark/32/26_2.png) [@quark](https://discourse.processing.org/u/quark)\
**Post date:** [September 4, 2022, 8:34am UTC](https://discourse.processing.org/t/pixels-array-p5-js-vs-java-improving-speed/38623/7 "2022-09-04T08:34:51Z")

</div>

Changing the draw method to

```auto
function draw() {
  p++;
  loadPixels();
  let t = pixels;
  for (let i = 0; i < t.length; i += 4) {
    c = k[(a[i] + p) & 127];
    t[i] = c._getRed();
    t[i + 1] = c._getGreen();
    t[i + 2] = c._getBlue();
    t[i + 3] = 255;
  }
  updatePixels();
}

```

will save a few bytes 😄

---

<div class="post-metadata">

**Author:** ![GoToLoop](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/gotoloop/32/86_2.png) [@GoToLoop](https://discourse.processing.org/u/GoToLoop)\
**Post date:** [September 4, 2022, 10:21am UTC](https://discourse.processing.org/t/pixels-array-p5-js-vs-java-improving-speed/38623/8 "2022-09-04T10:21:27Z")

</div>

> [@Sunt](#):
>
> My goal was trying to make a Processing’s tweet of it,

> [@Sunt](#):
>
> Still far too much characters. 😒

I was able to shrink my sketch version to merely 402 ( ~~386~~ ) characters within 80 columns. 🦐

Dunno if that’s enough for a tweet, but you can take a look at it running online: 🐦

> <https://gist.github.com/GoSubRoutine/0e87585b329421c24451cb42260ec311>
>
> There are more than three files. show original

Also leaving a copy of it in this forum: ©

```auto
R=42,G=84,B=128,V=600,S=32
I=Int32Array,A=new I(V*V),K=new I(B),f=0
setup=_=>{createCanvas(V,V)
pixelDensity(1).loadPixels(s=sin)
p=new I(pixels.buffer)
for(y=0;y<V;++y)for(x=0;x<V;)A[V*y+x]=B/4*(s(x/S)+cos(y/S)+s(sqrt(x*x+++y*y)/S))
for(i=0;i<B;)u=B*s(.12*i),
K[i]=color(R+u,G+B*s(PI/50*i+++.79),B+u).levels.reduce((a,v,i)=>v<<i*8|a,0)}
draw=_=>{++f
for(i=0;i<V*V;)p[i]=K[f+A[i++]&B-1]
updatePixels()}

```

---

<div class="post-metadata">

**Author:** ![Sunt](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/sunt/32/16827_2.png) [@Sunt](https://discourse.processing.org/u/Sunt)\
**Post date:** [September 4, 2022, 11:04am UTC](https://discourse.processing.org/t/pixels-array-p5-js-vs-java-improving-speed/38623/9 "2022-09-04T11:04:22Z")

</div>

That’s really nice. I still have to dive in to this to understand your code. BTW You might want to include “pixelDensity(1)”, otherwise, at least my computer, the canvas is not correctly filled. Twitter allows only 280 characters so it’s too big. I am working on a plasma code without the use of arrays to shorten the code and it works fine in java, but in p5.js it’s terribly slow. I don’t know if it’s possible.

`float x,a,t,y,b,d,s,c,p=0;void setup(){size(500, 500);colorMode(HSB,180);loadPixels();}void draw(){p++;for(int u=0;u<500;u++){x=u*0.02;a=sin(x);for(int t=0;t<500;t++){y=t*0.03;b=sin(y);d=sin((x+y+p*.1)/2);s=(a+b+d)/3;c=s*128+128;pixels[u+t*500]=color(c,255-c,255);}}updatePixels();}`

---

<div class="post-metadata">

**Author:** ![GoToLoop](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/gotoloop/32/86_2.png) [@GoToLoop](https://discourse.processing.org/u/GoToLoop)\
**Post date:** [September 4, 2022, 11:34am UTC](https://discourse.processing.org/t/pixels-array-p5-js-vs-java-improving-speed/38623/10 "2022-09-04T11:34:07Z")

</div>

> [@Sunt](#):
>
> Twitter allows only 280 characters so it’s too big.

Ru allowed to split the same code in multiple posts? ✂

P.S.: Added `pixelDensity(1)` to the code. Code increased from 386 to 402 characters. =(

---

<div class="post-metadata">

**Author:** ![Sunt](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/sunt/32/16827_2.png) [@Sunt](https://discourse.processing.org/u/Sunt)\
**Post date:** [September 4, 2022, 11:48am UTC](https://discourse.processing.org/t/pixels-array-p5-js-vs-java-improving-speed/38623/11 "2022-09-04T11:48:44Z")

</div>

I don’t know what you exactly mean by that. I am referring to the [https://twitter.com/tweetprocessing](https://twitter.com/tweetprocessing) page that states as requirment:

> Please post the Processing code that fits in one tweet with the hashtag #tweet Processing and the execution result!

---

<div class="post-metadata">

**Author:** ![GoToLoop](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/gotoloop/32/86_2.png) [@GoToLoop](https://discourse.processing.org/u/GoToLoop)\
**Post date:** [September 4, 2022, 12:37pm UTC](https://discourse.processing.org/t/pixels-array-p5-js-vs-java-improving-speed/38623/12 "2022-09-04T12:37:29Z")

</div>

> [@Sunt](#):
>
> , but in p5.js it’s terribly slow. I don’t know if it’s possible.

Diff. from Processing Java, where color is just a 32bit value, p5js creates a heavy p5.Color object every time we invoke **color()**, **fill()**, **stroke()**, etc.

As a workaround we can pre-create a _palette[]_ array filled w/ p5.Color objects.

For _pixels[]_ in particular, we can even pre-create an array of 32bit values, as I did on my sketch version.

---

<div class="post-metadata">

**Author:** ![Sunt](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/sunt/32/16827_2.png) [@Sunt](https://discourse.processing.org/u/Sunt)\
**Post date:** [September 4, 2022, 12:40pm UTC](https://discourse.processing.org/t/pixels-array-p5-js-vs-java-improving-speed/38623/13 "2022-09-04T12:40:28Z")

</div>

I understand, but now I am trying to avoid arrays to shorten the code length. The last java code I posted fits in a tweet.

---

<div class="post-metadata">

**Author:** ![GoToLoop](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/gotoloop/32/86_2.png) [@GoToLoop](https://discourse.processing.org/u/GoToLoop)\
**Post date:** [September 7, 2022, 11:12am UTC](https://discourse.processing.org/t/pixels-array-p5-js-vs-java-improving-speed/38623/14 "2022-09-07T11:12:59Z")

</div>

Python Mode bonus. However run it offline. It barely runs online:

https://trinket.io/embed/python/d45c76aa0a?toggleCode=true&runOption=run

---

<div class="post-metadata">

**Author:** ![Sunt](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/sunt/32/16827_2.png) [@Sunt](https://discourse.processing.org/u/Sunt)\
**Post date:** [September 7, 2022, 1:17pm UTC](https://discourse.processing.org/t/pixels-array-p5-js-vs-java-improving-speed/38623/15 "2022-09-07T13:17:36Z")

</div>

I don’t know Python, but honestly this speed is kind of disappointing!
