Alternative to for and while loops?

I‘m looking for an alternative for for and while loops. The functionality i‘m looking for is basically the speed given by a for loop or a while loop. The Problem lies in the fact, that if my for loop is too big (millions+) it stops the whole program and closes down… I know why, because it tries to get more operations per Frame done, than it could/Takes longer to finish the Frame than my System allows or similar. And that‘s where this new approach Would come in. Because the Same is valid (as far as i know) for a while loop. What i need, would be a way to call code multiple times in a second like a for/while loop, but without having it bound into one frame (don‘t know how that is supposed to work, But might as Well ask), or to call draw millions of times per Second (also not plausible, since draw does other stuff in the background and that could mess stuff up, or just be too much in General and Slow it all down anyway). What i might be able to do is to split a for loop into multiple Loops called in consecutive draw calls, But that would require some extra calculation that (although probably is not complicated and i prob could do pretty fast thinking about it now) choses what Part of the total to do in this Frame in this for loop, i Would still prefer to ask if there is an Alternative that is better. Or if there isn’t a better one, then in general an alternative, just to know it for the Future.

2 Likes

If you have a loop that is doing a lot, and you don’t want to bind its execution to the framerate, the simplest solution is to put your loop in a different function, and then create a new thread that runs that function. Here is an example:

int global_value;

void setup(){
  size(400,400);
  thread( "big_loop" );
}

void draw(){
  background(0);
  fill(255);
  text( global_value, 20, 20);
  translate(200,200);
  arc(0,0,380,380,0,radians((global_value)%360));
}

void big_loop(){
  while(true){
    global_value = global_value + 1;
    global_value%=10000000; // loop back around at 10M.    
    delay(1); // To run this loop as fast as possible, comment out this line.
  }
}
6 Likes

Thanks, that should be what i was looking for :blush:

It really depends a lot on the specifics of what you are trying to do – what is the output, and what is its relationship to time.

draw() is your outer loop. If you goal is to pack smaller drawing operations into frame times – but you can’t easily predict how long those will take – AND it doesn’t matter how they are split up – then you can just break out of a for or a while each time millis() gets too high. Finish the frame, update the screen, and keep going.

So, for example, say the problem is “I need to draw as many lines as possible as fast as possible (millions) but draw each batch within an FPS=60 window”. This sketch does that – when I inspect the frame rate, it hovers around 59, while the number of lines drawn per frame fluctuates – from ~170-240 lines-per-frame on my system. Rather than trying to pick a perfect number of lines, draw just draws lines until it is out of time, then updates the screen and continues.

int frameStart;
int totalCount;
void setup(){
  size(400,400);
  frameRate(60);
  background(192);
  colorMode(HSB, 50000, 1, 1);
}
void draw(){
  stroke(totalCount%50000, 1, 1);
  int count = 0;
  frameStart = millis();
  while(millis() - frameStart < (1000/60)){
    line(random(width), random(height), random(width), random(height));
    count++;
  }
  totalCount += count;
  println(frameRate, count);
}

Note this is not a threaded solution. Threads are perfect for some problems, but the big issue with threads and Processing arises when you actually want to draw [edit: on the main canvas] – you can’t do that from thread().

You cannot draw to the screen from a function called by thread() . Because it runs independently, the code will not be synchronized to the animation thread, causing strange or at least inconsistent results. Reference / Processing.org

3 Likes

Another solution is not to process the whole array in one frame. If you have aa array of length 1,000,000 then process 10,000 per frame the whole array would then at 60fps it take about 17s.

1 Like

It shouldn’t mutate the sketch’s main canvas. But a Thread can surely have its own PGraphics. :thread:

2 Likes

Thanks, But in my case i only Need to process data, so the Thread is pretty much ideal^^ i‘m working with a queue, so Splitting the actual array is not possible(it is, but i Would have to have multiple Queues and that would just complicate things), although i could just do the calculation in a for or while <10000 loop, but the Thread is pretty much optimal ^^. Thanks for the Suggestions :blush:

1 Like