8bitrocket.com
3Aug/090

Clayton Grey's Blit Layer Erase Speed Test

Clayton Grey's Blit Layer Erase Speed Test

A super diligent and incredibly intelligent (aren't you all) 8bitrocket
reader (and now contributor), Clayton Grey has been running some tests
on blitting entire screen-sized portions of BitmapData to clear the
screen and re-paint.   He doesn't have a blog of his own, and
asked that we present his findings. I am more than happy to because I
have been meaning to do the exact same test.  Clayton 
found that clearing an entire blit canvas can actually take
more time than the actual re-blit of the game screen layer. Because of
this, he tested as many methods of clearing the screen as possible and
found that copyPixels is still the king . That's great,  as I
have always relied on copyPixels for my blit erase operations.

Here are the results of Clayton's first round of tests: I've
left out his comments on the fact that he had to do this because I
haven't done any tutorials in a while. That would be because all of my
current best stuff is going into a new book and I will start new
tutorials after it has been finalized and sent to the publisher.

The results are timed in milliseconds with a getTimer() and the
beginning and end of the test (full source is below).

Tests
Round 1

My test results are as
follows on an 8-core Mac Pro:

For
1,000 iterations:

Fill w/ Alpha: 231
Fill w/o Alpha: 230
Copy + Alpha Merge True: 108
Copy + Alpha Merge False: 126

For
100,000 iterations:

Fill w/ Alpha: 23457
Fill w/o Alpha: 24056
Copy + Alpha Merge True: 11294
Copy + Alpha Merge False: 12229


Copying a blank with alpha merge is the clear winner here (though the
difference between alpha merge on and off is marginal) there an ~205%
increase in speed for blitting an empty canvas. I re-ran the tests once
more with a final step of filling the "blank" with a color (which I
imagine could be any background...)

For
1,000 iterations:

Fill w/ Alpha: 231
Fill w/o Alpha: 230
Copy + Alpha Merge True: 107
Copy + Alpha Merge False: 114
Filled Blank Copy + Alpha Merge True: 107
Filled Blank Copy + Alpha Merge False: 124


For
100,000 iterations:

Fill w/ Alpha: 23425
Fill w/o Alpha: 24036
Copy + Alpha Merge True: 11213
Copy + Alpha Merge False: 12152
Filled Blank Copy + Alpha Merge True: 11303
Filled Blank Copy + Alpha Merge False: 11591

Pretty similar. As such even if you're using a solid background color,
unless it's some sort of animated gradient, you're better off caching
it in a a bitmap "blank".


Test
Round 2

1,000 Iterations:

setPixels() with Lock: 2162
setPixels() without Lock: 2161
draw() with Lock: 768
draw() without Lock: 755
clone() with lock: 2390
clone() without lock: 2354
fillRect() w/ Alpha w/ Lock: 249
fillRect() w/ Alpha w/o Lock: 241
fillRect() w/o Alpha w/ Lock: 233
fillRect() w/o Alpha w/o Lock: 231
copyPixels() + Alpha Merge True w/ Lock: 106
copyPixels() + Alpha Merge True w/o Lock: 105
copyPixels() + Alpha Merge False w/ Lock: 133
copyPixels() + Alpha Merge False w/o Lock: 135
Filled Blank copyPixels() + Alpha Merge True w/ Lock: 104
Filled Blank copyPixels() + Alpha Merge True w/o Lock: 104
Filled Blank copyPixels() + Alpha Merge False w/ Lock: 126
Filled Blank copyPixels() + Alpha Merge False w/o Lock: 130

I did each method once with a lock() and unlock() as well as without (
just for kicks ). Again, I'm including the source. If you can think of
any other ways to fill BitmapData with empty pixels, add 'em.
copyPixels is still the fastest game in town.

Full
source


[cc lang="javascript" width="550"]

package com.laboratory.util
{
import flash.display.BitmapData;
import flash.geom.Point;
import flash.utils.getTimer;

public class FillOrCopyTest
{
public function FillOrCopyTest()
{
var _cache : BitmapData = new BitmapData( 640, 480, true, 0x000000 );
var _blank : BitmapData = new BitmapData( 640, 480, true, 0xFF0000 );
var _point : Point = new Point();

var i : int;

var time : int;

time = getTimer();

for ( i = 0; i < 100000; ++i ) { _cache.fillRect( _cache.rect, 0x00000000 ); } time = getTimer() - time; trace( "Fill w/ Alpha: " + time ); time = getTimer(); for ( i = 0; i < 100000; ++i ) { _cache.fillRect( _cache.rect, 0xFF0000 ); } time = getTimer() - time; trace( "Fill w/o Alpha: " + time ); time = getTimer(); for ( i = 0; i < 100000; ++i ) { _cache.copyPixels( _blank, _blank.rect, _point , null, null, true ); } time = getTimer() - time; trace( "Copy + Alpha Merge True: " + time ); time = getTimer(); for ( i = 0; i < 100000; ++i ) { _cache.copyPixels( _blank, _blank.rect, _point , null, null, false ); } time = getTimer() - time; trace( "Copy + Alpha Merge False: " + time ); _blank.fillRect( _blank.rect, 0xFF0000 ); time = getTimer(); for ( i = 0; i < 100000; ++i ) { _cache.copyPixels( _blank, _blank.rect, _point , null, null, true ); } time = getTimer() - time; trace( "Filled Blank Copy + Alpha Merge True: " + time ); time = getTimer(); for ( i = 0; i < 100000; ++i ) { _cache.copyPixels( _blank, _blank.rect, _point , null, null, false ); } time = getTimer() - time; trace( "Filled Blank Copy + Alpha Merge False: " + time ); } } } [/cc]



What do you think of Clayton's tests? Pretty comprehensive, I think. If
you have any questions or comments, leave them below. Clayton will be
around to answer them or he might even contact you if you want to offer
more advice or have questions that won't fit in the comment box.

If you enjoyed this post, please consider leaving a comment or subscribing to the RSS feed to have future articles delivered to your feed reader.
Comments (0) Trackbacks (0)

No comments yet.


Leave a comment

No trackbacks yet.

This site is protected by Comment SPAM Wiper.