I designed a datafield which shows a lot of information. Some of that information needs to be calculated (like lap pace, 60 sec pace, 10 sec pace, etc). Apart from this I have some string format calculations and some (maybe a lot) drawings to do. During my last run I realized that:
a) the datafield's graphics updates only every 2nd second
b) the last lap time (I visualize the current lap time and the last lap time via the datafield) is sometimes 3 seconds behind that lap time the watch calculates for its own (and sometimes not - i. e. I loose some +1 events)
c) the lap pace jumps around up to plus/minus 10-15 seconds during the lap (which is not if you simulate the run afterwards in the simulator)
I checked my code and realized e. g. that I converted the elapsed time from ms to seconds in every pace calculation, in fact I did that 4 times. OK, no problem, I refactored the code here. Furthermore I handled the calculation of lap time in two different threads seperately. I have to refactor the code to calculate and use the lap time just once.
After this obvious optimizations there are several more left which I want to discuss here:
1. The algorithms itself to calculate the paces
2. The math algorithm to ease the micro processor's life
3. The drawings
To 2.:
For the 60 seconds pace I have written this:
sixtySecondsSpeed = ((sixtySecondsSpeed * 59) + info.currentSpeed ) / 60;
Maybe it is more effective for the micro processor to code something like this:
sixtySecondsSpeed = (sixtySecondsSpeed * 64) - sixtySecondsSpeed;
sixtySecondsSpeed = (sixtySecondsSpeed + info.currentSpeed) /64;
IMO the second implementation could be much more efficient since the multiplication and division is just a bit shift for the micro processor. The disadvantage is that the average is now a 64 seconds average, but this is negligible.
Maybe the same is valid for comparison of counting values: I have e. g. this code:
if (LapTime < 20) { do something } else { do other stuff }Maybe it is more efficient to code this:
if (Laptime = 0) { LapTimeSmallerThanTwenty = true; }
if (Laptime = 20) { LapTimeSmallerThanTwenty = false; }
if (LapTimeSmallerThanTwenty) { do something } else { do other stuff }What do you think?
To 3.:
I have to do all of the drawings again and again in the onUpdate() method. IMO this is not efficient since a lot of parts of the datafield are static (like lines and labels). Therefore I tried to use a layout but the datafield gets very fast out of memory if I define all the datafield's lines and labels in the XML file. Therefore I am seeking for an option which is more efficient than drawing the same every second. Any hints on that?
To 1.:
Algorithm to get to the mean values. I showed in (2.) above how I calculate the mean values of the 10 seconds and 60 seconds pace. Nevertheless, maybe there is a better and more efficient way to calculate the 10 seconds pace. Apart from the algorithm itself I could use a 8 seconds or a 16 seconds pace and would ease the compiler's resources as I showed in (2.). But I consider to update the entire algorithm:
1. I define an array with 10 elements and use it as a FIFO
2. I write the following (pseudo) code (note that tenSecondsSpeedSum shall be the sum of all array values):
tenSecondsSpeedSum = tenSecondsSpeedSum - tenSecondsSpeedArray[0] + info.currentSpeed;
tenSecondsSpeedArray[0:8] = tenSecondsSpeedArray[1:9];
tenSecondsSpeedArray[9] = info.currentSpeed;
tenSecondsSpeed = tenSecondsSpeedSum / 10;By doing this I have the following advantages:
- I get rid of the multiplication
- I get a real 10 seconds average
but I get following disadvantages:
- I get an additional minus operation
- I need to define an array with 10 elements which needs memory
What do you think?