Go Down

### Topic: Simple Code Optimizations (Read 3240 times)previous topic - next topic

#### NullEntity

##### Oct 14, 2009, 05:15 am
Too be frank, I suck at programming. Recently, I learned I could change:
Code: [Select]
`if(bool == true){        bool = false;} else {        bool = true;}`

into

Code: [Select]
`bool != bool;`

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

#### westfw

#1
##### Oct 14, 2009, 10:33 am
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: [Select]
`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: [Select]
`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.)

#### NullEntity

#2
##### Oct 14, 2009, 01:29 pm
Thank for the information! That's actually pretty interesting.

#### kg4wsv

#3
##### Oct 14, 2009, 01:54 pm
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.   )

-j

#### ahdavidson

#4
##### Oct 14, 2009, 02:37 pm
or...

Premature optimization is the root of all evil!
.andy

#### retrolefty

#5
##### Oct 14, 2009, 06:00 pm
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

#### ahdavidson

#6
##### Oct 14, 2009, 06:29 pmLast Edit: Oct 14, 2009, 06:36 pm by ahdavidson Reason: 1
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.
.andy

#### pracas

#7
##### Oct 18, 2009, 06:52 pm
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
Be The Change...

#### Udo Klein

#8
##### Oct 20, 2009, 12:26 am
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

#### Mike Murdock

#9
##### Oct 25, 2009, 10:53 pm
NullEntity,

Code: [Select]
`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: [Select]
`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: [Select]
`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

#### Mike Murdock

#10
##### Oct 25, 2009, 10:57 pm
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

#### annodomini2

#11
##### Oct 27, 2009, 09:48 pmLast Edit: Oct 27, 2009, 10:30 pm by annodomini2 Reason: 1
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.

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.

#### kg4wsv

#12
##### Oct 27, 2009, 10:45 pm
Quote

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

#### AWOL

#13
##### Oct 29, 2009, 01:55 pm
Quote
Modern compilers will identify the former and optimize it into the latter

Quote
http://en.wikipedia.org/wiki/Strength_reduction
"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.

#### AlphaBeta

#14
##### Oct 29, 2009, 05:36 pm
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;

Code: [Select]
`if (a>b){  c = 2;} else {  c = 4;}`

You can do:
Code: [Select]
`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: [Select]
`if (angle>0){  if (angle<180){    if (speed>0){      forward = true;    }  }} else if (angle >= 180 && speed<0){  forward = true;}`

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

Happy Coding!

Go Up

Please enter a valid email to subscribe