Frame timer
Sometimes when you are developing sketches, it is useful to know how performance is affected by changing the sketch rendering style, the data used or the program design. The FrameTimer class simplifies the task of reporting the speed at which your sketch is being drawn.
Using the frame timer in Processing
The FrameTimer class can be found in the root of gicentreUtils package. To use it you should import the class into your sketch with the line
import org.gicentre.utils.FrameTimer;
For full details of the methods available see the FrameTimer API reference.
The simplest way to use a frame timer is to get it to report the number of frames drawn per second by calling the displayFrameRate() method inside your draw() loop.
For example,
import org.gicentre.utils.FrameTimer; // Simple sketch to demonstrate how a frame timer can be added // to a sketch to see how fast it is drawing. // Version 1.1, 5th November, 2013 FrameTimer timer; // This should be declared outside any methods. void setup() { size(400,400); timer = new FrameTimer(60); // Initialise to report every 60 frames. } void draw() { background(255); timer.displayFrameRate(); // Display number of frames per second. // Do some drawing of randomly placed and coloured ellipses. for (int i=0; i<1000; i++) { fill(random(0,150),random(0,150),random(0,150)); ellipse(random(10,width-10),random(10,height-10), random(4,10),random(4,10)); } }
The timer object should be created outside of any methods and initialised in setup(). The reporting of the frame rate (number of times the draw() loop is called per second) is done in this example using displayFrameRate(). This will report the frame rate to the console and is probably most useful debugging and optimising a sketch as you develop it.
If you wish to incorporate the frame rate into your sketch itself you can instead call getFrameRate() or getFrameRateAsText(). These return the current frame rate either as a float or String. Examples of use might be to display the frame rate within the sketch, or to adapt the drawing of your sketch to simplify things when the frame rate drops.
Rate 'by frame' and 'by time'
There are two ways in which the frame timer can be created, either to report the frame rate after a fixed number of draw() method calls (as in the example above that displays the frame rate every 60 frames), or to report the frame rate after a fixed number of seconds. The latter approach is particularly useful when frame rates are very low. To use the 'by time' approach, the two-argument constructor is used, where the first argument is the delay before the first frame rate calculation is used, the second is the frequency at which frame rates are reported. Both arguments are in seconds, and can be fractional. As an example, the following sketch reports the frame rate every two seconds regardless of the speed of drawing. The complexity of the drawing can be controlled with the left and right arrows:
import org.gicentre.utils.FrameTimer; // Frame timer that reports at regular time intervals. // Version 1.1, 5th November, 2013. private FrameTimer timer; private int numEllipses; void setup() { size(500, 200); timer = new FrameTimer(2,4); // Report every 4 secs after 2 sec delay numEllipses = 1024; textSize(18); textAlign(RIGHT, TOP); } void draw() { background(255); timer.update(); // Needed as we are using time-based frame counter. // Do some drawing of randomly placed and coloured ellipses. stroke(0, 120); for (int i=0; i<numEllipses; i++) { fill(random(0, 150), random(0, 150), random(0, 150), 80); ellipse(random(10, width-10), random(30, height-10), random(8, 20), random(8, 20)); } fill(0, 160); String fps = timer.getFrameRateAsText(); if (fps.length()>0) { text(numEllipses+" ellipses drawn at "+fps+" fps", width-5, 0); } } void keyPressed() { if (key == CODED) { if ((keyCode == LEFT) && (numEllipses>1)) { numEllipses /=2; } else if (keyCode == RIGHT) { numEllipses *=2; } } }
Avoiding pitfalls
It is important not to mix 'by-frame' and 'by-time' based reporting of frame rates. You should choose which one is most appropriate for your sketch and stick to it. For 'by-frame' based reporting, you will use either the default constructor (new FrameTimer()) that will default to recording frame rates every 50 frames, or new FrameTimer(numFrames) where you specify how many frames are to be drawn between reports of the frame rate. Here you should make exactly one call per draw() cycle to displayFrameRate(), getFrameRate() or getFrameRateAsText(). Calling any of these methods more than once will overestimate the number of frames drawn in a given time.
If you use a 'by-time' counter, you use the two-argument constructor (new FrameTimer(delay, frequency)). In this case, you must make one and only one call to update() in your draw() loop. but you can call displayFrameRate(), getFrameRate() or getFrameRateAsText() as many times as you wish.