| << previous entries | next entries >> |
Balázs Flash, Java and related technologies |
In this section we will examine the speed of loops with the three number types. The code is simple: var a:Number = 0; for(i = 0; i < 10000000; i++) a = 1; we just set a number to be 1. Okay, let's run the test above in three cases: i is an int, uint and Number. The results: int 78 ms uint 94 ms Number 140 ms Amazing. |
Balázs Flash, Java and related technologies |
"Dear Master, if I can create a Point using the Point.polar() method, why on earth can't I reuqest the angle of a Point? Please answer me, you are my only hope. The Little Grasshopper" Good question, I could have thought about it myselft. I guess the actual answer is that a Point is not a vector therefore there is no need to calculate any angle as there is no angle for one point. But, come on, why not to think about a point as a vector originated from (0, 0)? We are using a graphical program in the end, so a point is a vector. public function get angle():Number public function set angle(angle:Number):void AND! It is also good to know in which quarter (of the unit-radius circle) is our point. Also to set this. public function get quarter():int |
Balázs Flash, Java and related technologies |
Okay. Here we are with the second question. Can we fasten the request for length? - asked the little grasshopper. Yes, we can. The result is a 15% speedup. override public function get length():Number We have to mark the getter for override. That is all. By the way, try not to use the built-in Math.pow() for powering if you know the exponent. "Dear Master, Why is length a read-only property? I wanna set the length. Please make it possible for me. Thank you for you time The Little Grasshopper" We got this letter earlier and wan't to respond to it. We don't want to have suffering flash coders around our household. And for your information here is the trick: public function set length(length:Number):void if(x == 0 && y == 0) angle = 0; x = Math.cos(angle) * length; First we get the angle of the point: var angle:Number = x >= 0 ? Math.atan(y / x) : Math.atan(y / x) - Math.PI; and keeping this angle we set the new coordinates: x = Math.cos(angle) * length; for more information see the definition of sine and cosine. Isn't this awesome? We expanded the Point class! Of course, as it is written in Little Grasshopper's second letter (1), requesting the length is a dynamic metho, meaning that it calculates the length instead of using a constant. But. Since we don't want to make a setter for the coordinates (optimizing issues - just think about it), we can't catch the moment of chaning such a value. Therefore we can't use a constant for the lenght (what otherwise could be an optimising step). It has to be considered when to use it. |
Balázs Flash, Java and related technologies |
Point class is not a final class therefore we can extend it. To do this is quite useful because the main functions of points are in the package so you don't have to rewrite them. But still there are some extra things what you can override to get better results concerning speed. Let's see a simple test with the distance method. The distance method is a static type which calculates the distance between to give points. Quite easy and simple to use: var distance:Number = Point.distance(p1, p2); This is very useful in several calculations, we won't say anything more because it's that fundamental. But. Here comes the interesting part. I use the method and my program is really clean, but what do I get for my efforts? Somehow these built in packages run slowly if we run our optimum-searching code. Try it for yourself: on my machine it needed around 117 ms to run a 100.000 times. BUT THIS IS AWESOME!!! - could the little grasshopper say. I don't need to know maths and this function is superfast! What do WE say? : HA-HA (slow motion). Since we already have the skeleton of the extended Point class (remember to call super() with default x and y coordinates in the constructor) we override the SLOW distance method. public static function distance(p1:flash.geom.Point, p2:flash.geom.Point):Number There you go. And, my little padawan, yes. We came to see where the rabbit hole goes. Actually, we are in the rabbit hole. The result of the same test concerning the speed is: 41 ms. Let me say it again FORTYONE milliseconds. Let's stop for a minute. Little Grasshoper: Is this really 3 times faster than the built-in code? We: Obviously. We don't say that the errorchecking is the same for our own function and the built-in one. We don't check the type of object passed to the function and blabla, but that is so expensive! You have to be careful as there is no errorchecking but this is still really profitable. One more thing to know. We have the extended Point class now, let's say the package is org.geometry. How do you make a difference between this new one and the original class? Here is the trick: var p1:flash.geom.Point = new flash.geom.Point(10, 10); Note that the classes are prefixed with their packages. And this is our first step to optimize the Point class. The code: package org.geometry |
Balázs Flash, Java and related technologies |
Using trignometric functions brings up a question of memory. Trigonometric functions are famous about slowing down everything... (if they're not, then we say it now). The 50 point question is: is there a way to fasten Math.sin(x)? The answer is yes, there is. But you have to consider one thing. Math.sin() function returns with a relatively high precision. Probably you won't find a way to override the speed of that precision, but actually, do we need that? If you are not writing a high precision calculator, but handling pixel-level animations, how much do you need? Let's say first we want to reach a 4 digit precisity. This is what we have in mathematical tables, this is what people used over the centuries... Okay, but how do we calculate the sine? Our beloved mathematics gives us the solution. There is a known mathematical function called Taylor-function (discovered by the hindi science long time ago). Taylor-function is our friend in this battle. Calculating the right length of the so called Taylor-serie of sine gives the desired precision. How does this look like? Good question. sin(x) = x - x^3 / 3! + x^5 / 5! - x^7 / 7! + x^9 / 9!-... there you go. so, we know now the secret, let's translate this to flash-language: function taylor1(x:Number):Number x -
As you can see we left out Math.pow() aswell and calculated all the factorials. Since we want to optimize our code some additional steps can be done: - leave out division. You can calculate 1 / n for each n, where n is the specific factorial. But we did something else: Create variables outside the taylor function like: var a1:Number = 1 / n! (how to calculate n factor is up to you). - don't create local variable sin:Number. just return the whole number. Here it is: function taylor2(x:Number):Number Let's see some results: Math.sin() runs 1 million times at an average of 3703.6 ms and the Taylor-trick: 2601 ms. Yes. True. Precision is the key. Question: do other functions have their Taylor-series aswell? Good quesion, little padawan. Yes. Every Math class function has its own Taylor-serie. |
Balázs Flash, Java and related technologies |
This time we will go a bit deeper and see if flash code can be optimized (what a question!). Of course it can be. We are not talking about single 1-2% optimization, but heavy stuff here. Our frame code will be a counter and a cycle. For a million times we will run several algorithms, which in our case will give the same result - but not in the same time!
Let's see our code:
var array:Array = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]; for0(); //for1();
As you can see we will measure the runtime of a simple for loop. In the first case we set the limit to array.length, second, we create a variable, calculate the length first, and put this as a constant value to the cycle. We run both functions 9 times, and calculate the average and deviation. Results of first algorithm:
average: 1167, deviation: 1.05 Results of second algorithm:
average: 414.67, deviation: 2.05 AMAZING RESULTS! practically you can say that the second way is 2.81 times faster! That's something to consider. Your code needs 35.47% of the time to run! I think this needs no further explanation. Furthermore, if you dig deeper and deeper, you will always find a way to dramatically optimize your flash code. |
