Is millis() heavy on CPU program efficiency?

Hello Forum,

I am working a project running p5js sketches from Open Processing on mobile devices. I have the need to create a series of timed events with millis() but this slowing things down greatly! Are there efficient strategies for multiple events timed that are better than millis()?

Thanks for your help!

Margaret

1 Like

Hello,

I can’t comment on efficiency…

In Processing I have used frameCount:

I do not know how stable the frameRate is using P5.js on an Android.
Your mileage may vary depending on what you’re sketch is doing; I often monitor frameRate to see if sketch is slowing things down and work to optimize code.

:)

2 Likes

I found this interesting enough to test, and you are right; using millis() in a loop drove my CPU use up to a level of 55%!
Using frameCount (as glv suggested), in a loop , does not give significant alternation.

1 Like

The frameCount approach is very light but is bound by the frameRate():
p5js.org/reference/#/p5/frameRate

Another good performant approach is setTimeout():

I’ve got a wrapper class for it named Countdown btW:

3 Likes

@GoToLoop Thanks for pointing me out to the java timer utilities.
The most concise code I could make is this one.

import java.util.Timer;
import java.util.TimerTask;

void setup() {
  size(500, 500);
  background(255);
  Timer timer = new Timer();
  TimerTask task = new TimerTask() {
      public void run() {
      println(millis());
    }
  };
  println("Start time = "+millis());
  println("Sheduled 50ms timer task = 3 seconds");
  timer.schedule(task, 3000, 50);
}
3 Likes

Thank you to all who helped me wrap my head around millis() and programming timers!

Hi GoToLoop,

This solution is a little over my heard :slight_smile: Is this something I could use on OpenProcessing with p5Js to solve this problem:

There are at least 3 ways to tackle that:

  1. Use p5js’ own millis().
  2. Use JS’ setTimeout().
  3. Use my Countdown class, which is a wrapper for setTimeout() btW.

If you decide to pick my “library” class, you just need to copy & paste the contents of its file “countdown.js” onto a new tab from OpenProcessing.

The other file “sketch.js” is merely some silly example on how to use the wrapper class Countdown.

Basically what the class Countdown does is set its property done to true when setTimeout() triggers.

So you’re gonna need to continuously poll the status of property Countdown::done in order to know whether the wait time is over.

The milliseconds wait time is stored in property Countdown::delay and it’s initialized by the argument passed to constructor.

The wait time begins when we call the method Countdown::start(), which automatically calls clearTimeout() to cancel previous setTimeout() & sets Countdown::done to false.

If you need different wait times just create more instances of class Countdown.

2 Likes

Hi GoToLoop - first thank you! I have been playing with your ideas and testing some others from other code friends too. In the end, I found a solution with setInterval() which worked best for my particular project. Here’s a reduced version of how it works for me:

'use strict';

var button;


let timer = 0;
let startProgram = false;
let loaded = false;




function setup() {

    loaded = true;
    beginButton()
    createCanvas(windowWidth, windowHeight);

    console.time('time')
    noSmooth(); //does this improve running?
    console.timeEnd('time')
}


function beginButton() {
    let col = color(255);
    let col2 = color(0);
    button = createButton("begin");
    button.mousePressed(beginExperience);
    button.position(width / 2 - 30, height - 40);
    button.size(60, 25);
    button.style('background-color', col);
    button.style("color", col2);

}

function draw() {

    background(0);
    if (startProgram == false || loaded == false) {
        showLoading();
    }

    //start automations & timer when button pressed	
    else {
 		
			if (timer<=5){
				fill (0,255,0);
			}
			else if (timer>5&&timer<=10){
			fill (255,0,0);
			}	
			else if (timer>11){
			fill (0,0,255);
			}	
      ellipse(mouseX,height/2,100,100);
			
			//timer report
			textSize (20);
		  text (timer,width/2,100);
			
    } //close timed events/experience screen

} //close draw




function beginExperience() {
    setInterval(() => {
        timer++;
    }, 1000)
    button.remove();
    startProgram = true;
}


function touchMoved() {
    return false; //this prevents dragging screen around on mobile
}


function showLoading() {
    background(0);
    textAlign(CENTER, CENTER);
    rectMode(CENTER);
    text('loading...', width / 2, height - 30);
}
3 Likes