Ex Nihilo

A Processing Sketch Blog

Archive for the ‘Best Practices’ Category

CPU Usage in Processing

Thursday, November 5th, 2009

I’ve known for a while now that Processing — and Elevation in particular — is a bit of a CPU hog, as evidenced by the hum of the CPU fan frantically spinning every time I run a sketch. I had a vague idea of what the culprit might be, so it’s an issue I’ve meant to look into.

Let’s back up about 13 years for a second; in the mid 90′s I spent a lot of time cutting my teeth on programming in Basic, a popular beginner’s languages at the time. I was building fairly simple GUIs for applications and games, but even those were taxing what little processor speed I had available. Back then I stumbled across what I’d imagine to be a fairly core tenet of any sort of programming that involves drawing to the screen: don’t, if you can help it.

When you’re just starting out, you don’t really consider the work involved in throwing thousands of pixels at the screen every iteration, so you default to simply redrawing the screen during every cycle of your application loop. In the 90′s this was significantly more of a problem since the CPU just couldn’t keep up, and we had to learn to selectively redraw only when it was necessary. These days the processor speed is less of a barrier, so the temptation is there to use the extra power we have available. This is fine for learning, but when you’re producing something people are going to use, your application needs to be more responsible about how much of the CPU’s time it actually needs.

By the very nature of the draw loop, Processing isn’t really set up for optimization. The default mode is simply to draw, and redraw, and keep doing it over and over again. When you can take it for granted that the screen will be wiped every cycle, you don’t necessarily have to think about things like cleaning up old pixels before placing new ones. It’s convenient, but it comes at a price. Currently an instance of Elevation will run at something like 99% of CPU time, all the time, until it’s closed. This is a problem.

So last night I started digging into the problem to see if I couldn’t knock that down a little. The updated code is only available from the GitHub repo so far, but it’ll likely be rolled into the next version of the app.

I started by adding a global refresh variable that gets set to false, and then wrapped most of the draw loop contents in an if statement that checks to see if it’s been switched to true. Then just before the loop closes, I make sure to reset it back to false so the next loop won’t also redraw.

void draw() {

  if (scene.refresh == true) {
    // perform the redraw

  // reset the refresh switch for each loop so we don't peg the CPU
  scene.refresh = false;

The question now becomes, when is it appropriate to set refresh to true? That’s something I’m still working through; if I simply switch it back on in response to keyboard and mouse event handlers, that’s a start; but in Elevation I also have on-screen form controls that glow on hover, and switch images between when they’re selected and when they’re not. I now have to rework some of the assumptions those controls were making about the draw loop and code them to be a bit smarter about when they actually need to redraw.

Still, just these basic steps were a great start. Manipulating the scene with the mouse and zooming in and out will still tax the CPU, but as soon as you take your hands off the controls usage drops down from 99% to a more reasonable 4% or 5%. That’s progress.

Posted in Best Practices, Coding | 2 Comments »