Loading...
Logo
Processing Forum
Are there techniques to optimize a triple FOR loop with high dimensions?

Since the number of times the code is run increases exponentially, it gets slow real fast!

This does not make my frameRate happy

Here is some test code and the respective frameRates I got with it...

Copy code
  1. import processing.opengl.*;

  2. int dimensions = 50;

  3. // dimensions 10 = frameRate 1000+
  4. // dimensions 20 = frameRate 400
  5. // dimensions 30 = frameRate 130
  6. // dimensions 40 = frameRate 55
  7. // dimensions 50 = frameRate 29
  8. // dimensions 60 = frameRate 17
  9. // dimensions 70 = frameRate 11
  10. // dimensions 80 = frameRate 7
  11. // dimensions 90 = frameRate 5
  12. // dimensions 600 = frameRate :-(

  13. void setup(){
  14.   size(500,500,OPENGL);
  15.   frameRate(1000);
  16. }

  17. void draw() {
  18.   background(255,255,255);
  19.   translate(width/2-dimensions/2,height/2-dimensions/2,300);

  20.   for (int x=0; x<dimensions; x++) {
  21.     for (int y=0; y<dimensions; y++) {
  22.       for (int z=0; z<dimensions; z++) {
  23.         stroke(x,y,z);
  24.         point(x,y,z);
  25.       }
  26.     }
  27.   }

  28.   println("Frame: " + frameCount + " || FrameRate : " + frameRate);
  29. }

Replies(7)

I do not think that any real optimization is possible here. see, you have to run through dimensions^3 number of elements despite the style of code you use. I assume that not the FOR operator takes much time, but the graphic output.

You may try first storing the image into a PImage object and then displaying it. Although I assume, you need a dynamic display, right?
Yeah, in the actual sketch the values and image produced with(in) the FOR loops change on every frame. So it's not really static information nor a static image that can be stored and re-used unfortunately. Also the line "point(x,y,z);" which is the line causing much of the frameRate drop in this example, is the crucial one I use in the actual sketch.

As a non-programmer I'm just asking here, but could any of these be useful for something like this...
  • Bitwise operations
  • VBOs, PBOs and FBOs
  • Checking if the point(x,y,z) is on or off screen
Just wondering...
I got some frameRate improvements using opengl calls, so might investigate that route some more...

Copy code
  1. import javax.media.opengl.*;
  2. import processing.opengl.*;

  3. PGraphicsOpenGL pgl;
  4. GL gl;

  5. int dimensions = 200;

  6. // OPENGL RESULTS with all black points
  7. // dimensions 50 = frameRate 380
  8. // dimensions 100 = frameRate 53
  9. // dimensions 150 = frameRate 15
  10. // dimensions 200 = frameRate 7

  11. // OPENGL RESULTS with individually (remapped) colored points
  12. // dimensions 50 = frameRate 151
  13. // dimensions 100 = frameRate 20
  14. // dimensions 150 = frameRate 6
  15. // dimensions 200 = frameRate 3

  16. void setup(){
  17.   size(500,500,OPENGL);
  18.   frameRate(1000);
  19.   pgl = (PGraphicsOpenGL) g;
  20.   gl = pgl.beginGL();
  21.   gl.glPointSize(1.0);
  22.   gl.glColor3f(0,0,0);
  23. }

  24. void draw() {
  25.   background(255,255,255);
  26.   translate(width/2-dimensions/2,height/2-dimensions/2,300);
  27.   pgl.beginGL();
  28.   gl.glBegin(GL.GL_POINTS);
  29.   for (int x=0; x<dimensions; x++) {
  30.     for (int y=0; y<dimensions; y++) {
  31.       for (int z=0; z<dimensions; z++) {
  32. //        gl.glColor3f(map(x,0,dimensions,0,1),map(y,0,dimensions,0,1),map(z,0,dimensions,0,1));
  33.         gl.glVertex3f(x,y,z);
  34.       }
  35.     }
  36.   }
  37.   gl.glEnd();
  38.   pgl.endGL();

  39.   println("Frame: " + frameCount + " || FrameRate : " + frameRate);
  40. }

I think VBO's would help as might the clipping.  Here is an example of a displaylist.  Get pretty good performance out of that.
Copy code
  1. import javax.media.opengl.*;
  2. import processing.opengl.*;
  3. PGraphicsOpenGL pgl;
  4. GL gl;
  5. int displayList;
  6. int dimensions = 200;
  7. // OPENGL RESULTS with all black points
  8. // dimensions 50 = frameRate 380
  9. // dimensions 100 = frameRate 53
  10. // dimensions 150 = frameRate 15
  11. // dimensions 200 = frameRate 7
  12. // OPENGL RESULTS with individually (remapped) colored points
  13. // dimensions 50 = frameRate 151
  14. // dimensions 100 = frameRate 20
  15. // dimensions 150 = frameRate 6
  16. // dimensions 200 = frameRate 3
  17. void setup() {
  18.   size(500,500,OPENGL);
  19.   frameRate(1000);
  20.   pgl = (PGraphicsOpenGL) g;
  21.   gl = pgl.beginGL();
  22.   gl.glPointSize(1.0);
  23.   gl.glColor3f(0,0,0);
  24.   displayList = gl.glGenLists(1);
  25.   gl.glNewList(displayList, GL.GL_COMPILE);
  26.   gl.glBegin(GL.GL_POINTS);
  27.   for (int x=0; x<dimensions; x++) {
  28.     for (int y=0; y<dimensions; y++) {
  29.       for (int z=0; z<dimensions; z++) {
  30.         //        gl.glColor3f(map(x,0,dimensions,0,1),map(y,0,dimensions,0,1),map(z,0,dimensions,0,1));
  31.         gl.glVertex3f(x,y,z);
  32.       }
  33.     }
  34.   }
  35.   gl.glEnd();
  36.   gl.glEndList();
  37.   pgl.endGL();
  38. }
  39. void draw() {
  40.   background(255,255,255);
  41.   translate(width/2-dimensions/2,height/2-dimensions/2,300);
  42.   pgl.beginGL();
  43.   gl.glCallList( displayList );
  44.   gl.glEnd();
  45.   pgl.endGL();
  46.   println("Frame: " + frameCount + " || FrameRate : " + frameRate);
  47. }
OpenGL display lists are static ((( - thus it is not a complete solution. I remember having the same problem on drawing multiple OpenGL 3d-dots.. however I was using C++.

By the way, amnon.owed, your first code gives me 27 fps on my computer, and your OpenGL calls code gives only up to 6 fps... I have NVIDIA GeForce GTS 250. So different people will have different frame rate...

VBOs and PBOs can only give you static images... I suppose that using FBOs may help though (definitely, try it!). Checking if an object is out of view is essential to speed. It is much more viable for polygonal models, but dots are also graphics.

About bitwise operations - I am not sure, how can you apply them here...
Thanks guys. Will look into all this some more.

@noncom: I forgot to change the dimensions in the second code (in the code posted it's at 200), but if you put it at 50 like in the first example you can fairly compare the frameRates.

Oh, true I missed that... I see that in the  http://forum.processing.org/topic/opengl-and-p3d-slow-rendering thread, they advice to use a library...