Pages: [1]   Go Down
Author Topic: Simple Code Optimizations  (Read 1383 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Newbie
*
Karma: 0
Posts: 11
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Too be frank, I suck at programming. Recently, I learned I could change:
Code:
if(bool == true)
{
        bool = false;
} else {
        bool = true;
}

into

Code:
bool != bool;

I'm thinking that this would save a few operations on microprocessors that are a bit short on space. Any other tips?
Logged

SF Bay Area (USA)
Offline Offline
Tesla Member
***
Karma: 106
Posts: 6364
Strongly opinionated, but not official!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Actually, a reasonably intelligent compiler (which includes the one used by Arduino) will detect the logical equality of these two code segments (neither of which looks quite right for the arduino environment, but I get the idea.)  I added some test code to a sketch and looked at the object code produced for:
Code:
char test1 (char b)
{
  if(b == true)
  {
    b = false;
  }
  else {
    b = true;
  }
  return b;
}

char test2(char b)
{
  return !b;
}
It was IDENTICAL for the two functions; source length does not have a lot to do with final program size when you are using a compiler, and you should generally not "optimize" the way your source code looks at the expense of making your program harder to understand.

This PARTICULAR optimization usually shows up with functions like:
Code:
byte isspace(char c)
{  if (c==32 || c==9)
     return true;
     else return false;
}
vs
    return (c==32) || (c==9);
And I'm not sure I find the second statement to be more obvious.
It's NICE to write code the way you think, rather than the way you think the compiler will generate the best code.  That way you can still understand your code when you look at it again a few years later.  This does require a certain level of trust in the compiler, though, and perhaps adjustments if you move to a different language.  (Interpreted BASIC was infamous for encouraging bad programing practices because shorter programs ran faster, for example.)
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 11
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thank for the information! That's actually pretty interesting.
Logged

0
Offline Offline
Faraday Member
**
Karma: 7
Posts: 2526
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Something I was taught in CS class years ago that I've found to hold true:

when writing code, make it:

     1 correct
     2 easy to understand (and therefore easier to maintain)

Performance comes last.  Only worry about performance if you find there is a performance problem when executing your correct, clearly written code.

As westfw says, you can just write the code and let the compiler work its magic.  (I suspect black magic at high optimization levels.  smiley )

-j
Logged

Seattle, USA
Offline Offline
Full Member
***
Karma: 0
Posts: 248
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

or...

Premature optimization is the root of all evil!
Logged

.andy

Left Coast, CA (USA)
Online Online
Brattain Member
*****
Karma: 331
Posts: 16464
Measurement changes behavior
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Premature optimization is the root of all evil!

Probably correct, however not to be confused with picking the best algorithm to solve a given task. As I understand it that is the best optimization step and will have the biggest impact on size and speed of the overall program.

Lefty
Logged

Seattle, USA
Offline Offline
Full Member
***
Karma: 0
Posts: 248
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Right.

I was trying to echo kg4wsv's point that the primary criteria for algorithm selection should be correctness, then clarity, and only third, efficiency.

Make it right, might it comprehensible, then make it faster if it's too slow.
« Last Edit: October 14, 2009, 11:36:29 am by ahdavidson » Logged

.andy

Chennai, India
Offline Offline
God Member
*****
Karma: 0
Posts: 752
Peace!!!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I agree with west..

I used to do it often - finding the shortest ways to get an output and it would end up in a mess which nobody can even look at! I wouldn't even comment. One thing i've learnt with microcontrollers is to make intelligent use of variables. Use the ones taking less memory and giving the complete functionality you require. I remember long back when i used to use floats for looping from 1 to 10.. lol
Logged

Be The Change...

0
Offline Offline
Faraday Member
**
Karma: 19
Posts: 3418
20 LEDs are enough
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

And one more argument in the direction of not optimizing to much: if you are not planning to create thousands, consider the fact that the software costs (unless your time is absolutely free) dominate the hardware costs by far. So better stay on the understandable side and consider using a more expensive controller.

Once you are advanced enough to do the really nasty optimizations you are usually advanced enough to go for a STK 500 and a bigger controller. Or you might even consider firing up eagle and fix it in hardware smiley
Logged

Check out my experiments http://blog.blinkenlight.net

Huntsville, Alabama, USA
Offline Offline
Sr. Member
****
Karma: 2
Posts: 327
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

NullEntity,

If your program says
Code:
bool != bool;
It won't do what you are intending.  The variable 'bool' will not be changed.  To change 'bool' from true to false or vice versa, you want to write
Code:
bool = !bool;
It looks like you were trying to use an assignment operator, which performs an operation on two operands and then puts the result in the first operand.  For example, the two statments
Code:
a = a + b;
a += b;
do the same thing.  But assignment operators only work for binary operators, that is, operators that take two operands, like +, -, *, /, etc.  The ! operator is a unary operator, that is, it only takes one operand.  There are no assignment operators for unary operators.

By the way, the other unary operators are: ~ (takes the one's complement of the operand), ++ and --, although ++ and -- are technically prefix or postfix operators, depending on whether they come before or after the operand.

Your original post started a great discussion on optimization, so I hope you post more of your observations.

Regards,

-Mike
Logged

Huntsville, Alabama, USA
Offline Offline
Sr. Member
****
Karma: 2
Posts: 327
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I echo the sentiments of my fellow programmers on optimization.  You can try optimizing at random -- picking a section of code, optimizing it, and then trying it out to see if it makes a difference.  But, without measuring where the bottleneck is occurring, odds are your effort will be wasted.

Let's say that you find a section of code that is very inefficient.  You optimize it and it runs 100 times faster than before.  However, if that section of code only represents 1% of the cpu usage, you won't notice the difference.

-Mike
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 5
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Optimisation is dependent on the implementation of the ALU (Arithmetic and Logic Unit) of the microprocessor.

And the effectiveness of the optimiser in the compiler.

Certain optimisations work better with certain cores, for example:

Where multiplication and divide take many clock cycles (typical), where possible using shift operations to prevent underflow and overflow to rescale can under certain circumstances significantly speed up the process.

So instead of:

 word i = 25000;

 i /= 256;

You would use

 i >> 8;

There is a secondary benefit to this in these types of microcontrollers in that the number of clock cycles taken by the ALU to complete the operate is constant, which is very useful in real time control systems which this system is sometimes used in.

In PC systems the above is true that easier to understand and maintain code is preferable.

In embedded systems and more specifically real time, performance is everything, if you cannot match the required frequency response of the system, then it doesn't work. I'm not saying bad code is acceptable, but the first priority is for the product to work!

Ram and flash requirements are also considerations.

There are some options, increasing clock rate of the processor or changing the processor itself. But these are not always a possibility and software optimisation is typically your only route.

Secondly, readability of code is subjective to the user, those that are familiar with specific algorithms will not suffer from a misunderstanding of operation and so there is certainly an element of knowledge involved.

Handling of datatypes larger than the ALU core operation can also be a field of optimisation.

The 8-bit core of the atmel can only add, sutract, multiply etc 2 8-bit values at any one time so complex algorithms need to be used to support the operations for values greater than 8bit.

Reduction in the use of these types can offer run-time performance and ram usage benefits.

The Atmel also doesn't have an FPU (Floating Point Unit) these also require extra complexity in the mathematical operation over and above the fixed point operations.

Where possible avoid the use of floating point math when an FPU is not available and a fixed point operation will provide sufficient accuracy in the calculation.
« Last Edit: October 27, 2009, 04:30:09 pm by annodomini2 » Logged

0
Offline Offline
Faraday Member
**
Karma: 7
Posts: 2526
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
So instead of:

word i = 25000;

i /= 256;

You would use

i >> 8;

Modern compilers will identify the former and optimize it into the latter, if given sufficient leeway via the optimization level flag.

-j
Logged

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 238
Posts: 24298
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Modern compilers will identify the former and optimize it into the latter
Quote
Logged

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

Norway@Oslo
Offline Offline
Edison Member
*
Karma: 12
Posts: 2033
loveArduino(true);
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

If this thread is about optimizing the number of letters it take to express a condition, and or solution, I think one has to mention the ternary operator ?:

condition ? expression1; : expression2;

Typically, instead of doing:
Code:
if (a>b){
  c = 2;
} else {
  c = 4;
}

You can do:
Code:
c = (a>b ? 2 : 4);


Additionally, I think it's worth mentioning using if with multiple conditions.

( Check Comparison & Boolean Operators )


You can write this:
Code:
if (angle>0){
  if (angle<180){
    if (speed>0){
      forward = true;
    }
  }
} else if (angle >= 180 && speed<0){
  forward = true;
}

Like:
Code:
if ( (angle>0 && angle<180 && speed>0) || (angle >= 180 && speed<0) ){
  forward = true;
}

Happy Coding!
Logged

Pages: [1]   Go Up
Jump to: