![](templates/subSilver/images/CCSLogo.jpg) |
![CCS C Software and Maintenance Offers](templates/subSilver/images/forumAd6.jpg) |
View previous topic :: View next topic |
Author |
Message |
Fabri
Joined: 22 Aug 2005 Posts: 275
|
Switch() statement and optimization |
Posted: Sat May 14, 2011 2:33 am |
|
|
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 |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19382
|
|
Posted: Sat May 14, 2011 2:57 am |
|
|
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 |
|
![](templates/subSilver/images/spacer.gif) |
Fabri
Joined: 22 Aug 2005 Posts: 275
|
|
Posted: Sat May 14, 2011 3:26 am |
|
|
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 |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19382
|
|
Posted: Sat May 14, 2011 8:18 am |
|
|
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 |
|
![](templates/subSilver/images/spacer.gif) |
|
|
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
|