CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

Switch() statement and optimization

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Fabri



Joined: 22 Aug 2005
Posts: 275

View user's profile Send private message

Switch() statement and optimization
PostPosted: Sat May 14, 2011 2:33 am     Reply with quote

Hi to all....

I use switch() statement in some program without any problem. Now I have to reduce use of memory because I need to introduce new firmware.

I tryed with if statement ad I reduced a bit of amount of used memory. But it isn't enough for my project.

Have you got any other solution to replace switch() and save momory ?

Thanks for help,

Regards,
Fabri
Ttelmah



Joined: 11 Mar 2010
Posts: 19338

View user's profile Send private message

PostPosted: Sat May 14, 2011 2:57 am     Reply with quote

Not without knowing a lot more.....

First, have you got a 'default' in your switch?. If you _don't_, provided there are more than perhaps 5 or six values, the compiler will normally code the switch as a jump table, rather than as separate tests. So it is more efficient, to do a 'pre test', like:
Code:

#define MAX_SWITCH (6)

if (val>MAX_SWITCH) {
    //code for default
}
else {
   switch (val) {
   case 0:
       //code
       break;
   case 1:
       //code
       break;
   case 2:
       //code
       break;
   case 3:
       //code
       break;
   case 4:
       //code
       break;
   case 5:
       //code
       break;
   case 6:
       //code
       break;
   }
}

Than to have an eighth 'default' line.

Like this the switch itself doesn't use much space. The above codes to just 39 bytes for the setup, and grows by just two bytes for each new switch entry.
It is also though worth looking at the 'nature' of your switch ranges. If (for instance), you have switch values of 0 to 6, then 24 to 32, again, test for the other values, before using two shorter switch tests for these sub ranges.

Generally though, it is normally the code in the switch elements that is using most space. Look at ways of reducing this. For instance, if you have multiple 'printf' statements, in different parts of the switch 'tree', consider is you can turn these into subroutines. If (for example), three of the printf statements use the same format specifier, better to have just one in a routine, and call this from the three required places. The same applies to any other bulky code (division for example).

Best Wishes
Fabri



Joined: 22 Aug 2005
Posts: 275

View user's profile Send private message

PostPosted: Sat May 14, 2011 3:26 am     Reply with quote

Deat Ttelmah,

Thanks for explanation. Really, value used in my switch statement is long so I wonder the compiler produce more code then 8 bit value. I used switch() statement in menu where high byte is pointer to menu and lower byte is pointer submenu. I'm thinking to use constant table....

Regards,
Fabri
Ttelmah



Joined: 11 Mar 2010
Posts: 19338

View user's profile Send private message

PostPosted: Sat May 14, 2011 8:18 am     Reply with quote

Sounds a terribly inefficient way to work.
You are creating tiny sections of switches, with enormous gaps between them. means the compiler cannot optimise to a jump table, and has to effectively to do sectional if tests for every value....
Obviously, yes, tests on 16bit values take more work than on 8bit ones, and even with the jump table approach, the table will be much larger, and the arithmetic involved more complex.

First thing to do, is look at what the largest number of sub menus is.
If (say), it is eight or sixteen, then code the sub-menu as the low three or four bits, not a whole byte. The range of values involved would drop massively. Remember you can use a union to combine a structure and a byte/word (depending on the total range involved). You may well be able to reduce the value used to a byte, rather than an int16. So:
Code:

struct men_entry{
    int8 sub_menu_entry:3;
    int8 main_menu_entry:5;
} menu_entry;

union {
    int8 bvalue;
    struct men_entry men_val;
} menu;

#define TOP (0)
#define SETUP (1)
#define OUTPUTS (2)
#define INPUTS (3)
#define SCROLL (4) //Some silly names as an example

#define ONLINE (0)
#define FORWARD (1)
#define MANUAL (2)

menu.men_val.sub_menu_entry=MANUAL;
menu.men_val.main_menu_entry=SCROLL; //Example accesses

switch (menu.bvalue) {
   case ((SCROLL*8)+MANUAL) : //Makes is easy to see what the entry is for
      //Here for the selected entry.
      break;
}

Or, use an ENUM, to give the names.

Best Wishes
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group