Optimizing Perlin Noise
Via todays post on nodename about Perlin Clouds and Frocessing I came across Ron Valstar’s AS3 version of Ken Perlin's Improved Noise reference implementation which I must have missed last year.
As Ron mentions the AS3 code runs way slower than the native perlinNoise() method that Flash's BitmapData class offers, but on the other hand his class is true to the original version and offers real 3D Perlin Noise and the possibility to control the falloff factor. So the reason for my belated post now is that I couldn't help noticing several opportunities to optimize the code. As usual optimizing will definitely not make code look better or easier to understand but for stuff like PerlinNoise which you usually called several hundred or thousand times every little counts to make it perform faster.
I attacked the class at the usual optimization points:
- Unroll functions wherever possible - this is usually the biggest timesaver. almost every function call in an inner loop is poison for execution time. The reason for that is that internally every call causes tons of save-data-on-stack and get-data-from-stack operations which do not happen if you copy the code that the function processes right into your loop.
- Do type casting whenever dealing with arrays in Flash. Especially for the indices - so instead of v = p[i+5] say v = Number( p[int(i+5)] ). That doesn't look as nice but it helps
You can see the result of this optimization here On the left is the original class, on the right the optimized one which turns out to be twice as fast. I had hoped for more but that's all I could do.
You can download OptimizedPerlin.as here or right-click the example and choose "View source".
Posted at July 11, 2008 07:04 PM | Further reading
Oh btw - in case anybody wonders why I left those three Math.floor in there: it turned out that the typical optimizations x>>0 or int(x) not always give the same result as Math.floor(x). int(x) works only for positive numbers and x>>0 is only correct for x < 0x80000000.
hi mario
great work!
btw. i'm not that expert of optimizations but have you tried to replace the for loops with while loops especially in the fill loop?
i tried it in a bitmap processing project and the performance boost was really amazing.
hi,
congrats to the author and thanks for sharing ;) (as always)
first comment on your blog, we met in Paris.
concerning the loops, yesterday a friend of mine noticed something strange regarding the loops.
I did a benchmark and it appears that the type of the max iteration is far more important than it seems(to me at least). while is not necessarily faster btw.
please have a look: http://en.nicoptere.net/?p=7
Mario > you (unwillingly?) pushed me to write in english (when we met in Paris, we took a taxi) my blog is for you ;)
Few suggestions here :
- don't use statics ! instead construct an instance and it should be a lot faster
- if you want to it be even faster, use haXe ;)
Great job Nicolas! About the statics: that was the first thing I changed in my optimizations but to my own surprise this didn't improve the performance at all. But maybe that was because I wanted to keep it a Singleton like the original class.
Wow, that's quite some speed increase :-) great job !
Gonna give it a go it right away.
And I'll try to remember the speed optimizations next time I write some processor hungry stuff.
I'm a newbie to Flex3 - could anyone provide a code example of this amazing routine for me to learn from? Cheers!