Time to time a developer has to ask from Self: “is this really the fastest way to do it?”
After some investigation in most cases the result is “no it wasn’t”. Here’s an example:
I have used (a little modified version of) the Andre Michelle’s port from Bresenhams line algorithm and always thought it would be the fastest way to draw a line on BitmapData in Flash.
I was playing with lines and asked my self the previous question. After some Googling I found this Extremely Fast Line Algorithm (EFLA) written by Po-Han Lin. I gave it a try and ported it to as3. By default it was way faster then the Bresenhams version, but after some AS3 specific optimizations it came out TWO times faster and here it is for you:
{
var shortLen:int = y2-y;
var longLen:int = x2-x;
if((shortLen ^ (shortLen >> 31)) – (shortLen >> 31) > (longLen ^ (longLen >> 31)) – (longLen >> 31))
{
shortLen ^= longLen;
longLen ^= shortLen;
shortLen ^= longLen;
var yLonger:Boolean = true;
}
else
{
yLonger = false;
}
var inc:int = longLen < 0 ? -1 : 1;
var multDiff:Number = longLen == 0 ? shortLen : shortLen / longLen;
if (yLonger)
{
for (var i:int = 0; i != longLen; i += inc)
{
this.bit.setPixel(x + i*multDiff, y+i, color);
}
}
else
{
for (i = 0; i != longLen; i += inc)
{
this.bit.setPixel(x+i, y+i*multDiff, color);
}
}
}

November 26th, 2009
6:26 pm
Interesting usage of bitwise ops. I suppose it’s a way faster than lineTo in low quality mode – another challenge for Jackson Dunstan ;)
November 26th, 2009
9:01 pm
Looks good, I’ll try it. Have you managed to test performance agains this class? http://www.bytearray.org/?p=67 – ah now I see it uses Bresenham as well, never mind, ignore me plz ;]
November 27th, 2009
9:31 am
Weard, I thought that it would be faster to do the following
this.bit.setPixel(int(x + i*multDiff), int(y+i), color);
But I only get a slight increase on execute time. Tested only on debug player though..
November 27th, 2009
10:02 am
If I place the algorithm inside loop (out of function) without the method call the execution is much slower, but now I can optimize it with int(x+i) and the result is slightly slower then using method call without int().
Conclusion: AS3 does the ‘Number to int’ transformations very properly for functions parameters and for some reason the setPixel(int(x+y), int(x+y)) inside the method is slow. wtf..
here are test results with debug player:
100000 lines
method call with int()
5086
5036
5061
5028
5038
5028
method call without int()
4879
4854
5040
4864
4888
4868
without method call (inside loop) with int()
5038
5062
5019
5022
5021
5029
without method call (inside loop) without int()
…much more
December 1st, 2009
7:01 am
[...] Extremely Fast Line Algorithm AS3 Optimized [...]
December 1st, 2009
8:42 pm
[...] simppa.fi/blog » Extremely Fast Line Algorithm AS3 Optimized [...]
December 2nd, 2009
2:04 am
Thanks for the algorithm and the port to AS3. I’ve taken Og2t’s advice and written an article comparing it to Graphics.lineTo(). You can read all about it on my site tomorrow here: http://jacksondunstan.com/articles/506.
Thanks again for the port!
December 2nd, 2009
9:06 am
[...] recent post by Simo Santavirta featured an algorithm with an irresistible name: Extremely Fast Line Argorithm. A comment on that article piqued my interest and I decided to test the algorithm out against [...]
December 2nd, 2009
1:01 pm
hi,
well done indeed
I’ve tested your take against Didier’s ( http://www.bytearray.org/?p=67 ) and your version is +/- 35% faster.
well done :)
December 3rd, 2009
5:17 pm
seem to get syntax errors with:
if((shortLen ^ (shortLen >> 31)) – (shortLen >> 31) > (longLen ^ (longLen >> 31)) – (longLen >> 31)) {
no matter what i try…
December 4th, 2009
8:05 pm
@sq2 – I had this too and it was really frustrating. It seems that the negative signs get copied over as something else (an em-dash?). Just delete them and re-type in manually in your text editor. It should work out just fine then. :)
February 3rd, 2010
4:10 pm
Great article, thank you for putting all of this information together.
March 6th, 2010
2:09 am
thanks great info here! I’m going to add a line width to this – I guess I will replace what I have below with a for loop which takes the width variable. Do you have any advice for me or a better solution?
thanks.
if (yLonger)
{
for (var i:int = 0; i != longLen; i += inc)
{
bitmapData.setPixel(x + i * multDiff, y + i, color);
bitmapData.setPixel(x + 1 + i * multDiff, y + i, color);
bitmapData.setPixel(x-1 + i * multDiff, y + i, color);
}
……………..
March 6th, 2010
8:01 am
I guess you might want to consider using bitmapData.fillRect() method. It could be much faster.
March 21st, 2010
2:03 am
great thanks, worked perfectly for me:
bitmapData.fillRect(new Rectangle(x-(size/2) + i * multDiff, y-(size/2) + i, size, size),color);
March 24th, 2010
2:45 pm
auch dave! create a new Rectangle() object into class and use it on every loop cycle:
rect.x = x-(size/2) + i * multDiff;
rect.y = y-(size/2) + i;
rect.width = rect.height = size;
bitmapData.fillRect(rect,color);
much faster.
May 29th, 2010
12:14 pm
This agorithm is the naivest possible.
I brewed the same code back in 2003 when i was just starting graphics programming. I had no interests to do reserch on line drawing and thus i didn’t know any other ways to do it. I had no interests for benchmarking and thus i never knew it was so fast.
Basically Bresenham Line Algorithm could be optimized with nested loops to get rid of the inner branch. In the case where dx > dy the inner loop itself could be replaced with horizontal line drawing code i.e. memset() making it blazing fast!
I think the root of Han-Po’s results is unevenly distributed level optimizing among line drawing algorithms making his implemetation seem fastest.
June 1st, 2010
12:35 pm
Good for you, Lauri.
How about sharing your method?
June 2nd, 2010
8:12 pm
I’m sorry for my too fast judgement – Breseham’s line drawing algorithm isn’t fastest on modern 32-bit hardware. Fixed point DDA is the fastest and Han-Po’s algorithm is actually nothing more than a fixed point optimized DDA line drawing algorithm with a new, fancy name.
So, Simo, you’ve got the fastest algorithm already. :)
June 4th, 2010
12:35 pm
ohh, shame :( Would have been nice to find even faster solution.
June 9th, 2010
9:27 pm
Actually i spoke too soon again – i wonder if Michael Abrash’s “run-length sliced Bresenham’s line drawing algorithm” is even faster than fixed point DDA (Han-Po’s implementation). I was estimating the amount of CPU cycles per pixel for both methods and it might even be that mr. Abrash’s code runs 2/3 faster… I do not know though, i haven’t tested/measured it.
For details please see http://downloads.gamedev.net/pdf/gpbb/gpbb36.pdf .