The Showdown: Clipping vs. Subimaging

Which one is faster? This is a benchmark in regard to a discussion over at javagaming.org: "clip an image"

A debate arose in that discussion about if clipping or using subimages was a faster rendering method. First, let's take a look at the methods in question.

Method #1: Clipping

In a Graphics context, clipping simply sections off a portion of the screen to be rendered to. In this particular case, we're clipping so we can draw individual frames of "sprites" from a spritesheet. This means that any time you want to draw a sprite frame (at least once per each screen update), the clip has to be recomputed.

My opinion: this method is a bit of bottleneck, why clip more times than you have to?

Method #2: Subimaging

Subimaging (not really an official term) is a process where each individual sprite frame is calculated and cached into memory for later use. The actual "clipping" (a.k.a. "cropping") is only performed once, and the sprite frames are drawn from memory. Because of this, Java pretty much sees it as a regular image, all it needs to do is plot the pixels, nothing more.

My opinion: this method is faster, it only performs the clipping once!

Method #3: drawImage

This one was kind of added last-minute, just out of curiosity. Basically this method uses only the drawImage method as provided by the Graphics class. We simply specify the coordinates of the source image and the coordinates to be drawn to the screen, we don't manually set any clips here.

My opinion: this should still be slower than subimaging, because it still has to recompute the pixels on each draw (the API clearly says that there is no image cache that it uses).

The Results

The benchmark can be downloaded below, but read these results before running the program since it runs in fullscreen (sorry, linux users).

The benchmark program is using this spritesheet:



And here are the results (your mileage may vary):

ModeSpritesFPS
Clipping:2575
drawImage:2575
Subimaging:2575
 
Clipping:10075
drawImage:10075
Subimaging:10075
 
Clipping:50037
drawImage:50037
Subimaging:50075
 
Clipping:75025
drawImage:75025
Subimaging:75072
ModeSpritesFPS
Clipping:100020
drawImage:100020
Subimaging:100060
 
Clipping:150015
drawImage:150015
Subimaging:150038
 
Clipping:200011
drawImage:200012
Subimaging:200032
 
Clipping:30008
drawImage:30008
Subimaging:300024
So, it seems, as I thought, subimaging seems to be the faster method. It appears subimaging is 2.5x-3x faster than clipping.
Interestingly enough, the clipping and drawImage modes seem to be identical. Possible internal clipping going on here?

Before running the program, take a quick look at the controls:

KeyFunction
+ (plus)Add a sprite
- (minus)Remove a sprite
spacebarchange rendering mode
anything elseclose program


Enjoy:
Run the program | View Source Code

* Java 1.4.2+ required