Replace switch/case by #ifdef or something similar - c

I'm trying to replace the switch/case structure by an other tool doing the same thing but with better performance ( less execution time ... ), I have in mind the #ifdef method but I have no idea how to use it in such situation:
float k_function(float *x,float *y,struct svm_model model)
{
int i;
float sum=0.0;
switch(model.model_kernel_type)
{
case LINEAR :
return result1;
case POLY :
return result2;
case RBF :
return result3;
case SIGMOID :
return result4;
default :
return 0;
}
}
PS :
typedef enum kernel_type {LINEAR, POLY, RBF, SIGMOID};

As I already commented, I do not believe preprocessor statements are what you are looking for. To use a preprocessor conditional, model.model_kernel_type would need to be a constant defined using a #define statement.
I do not know the internals of the switch statement, as it could be O(n) or O(1) depending on how the compiler handles it. If you needed to be sure of a O(1) time complexity, you could simply replace your switch statement with a lookup table like so:
float model_type_results[4] = {result1, result2, result3, result4};
...
return model_type_results[model.model_kernel_type];

I imagine the problem is not just 1 case statement, but code that is littered with similar case statements.
The c++ virtual function table is a similar concept for avoiding these sorts of case statements proliferating through the code. It is not actually difficult to implement function table semantics in C structures.
Traditionally, they have been written as just member function pointers, but the use of a single per-class function table pointer is more space efficient if there are many objects of each class.

#ifdef is a compile-time operation, not a run-time operation. It's not the solution you are looking for here.
Honestly, if your switch only contains four cases, there's not a lot you can do to improve on it. If you're seeing any kind of slowdown here, it's in how your results are being computed (which you don't show).

Related

Using an array of function pointer instead of switch

Is there any difference between using function pointer array and switch.
ı wrote a code like this
// Declaritons of add-substract-multiply funcitons
void (*fun_ptr_arr[])(int, int) = {add, subtract, multiply};
unsigned int ch, a = 15, b = 10;
printf("Enter Choice: 0 for add, 1 for subtract and 2 "
"for multiply\n");
scanf("%d", &ch);
if (ch > 2) return 0;
(*fun_ptr_arr[ch])(a, b);
and ı wonder what would be better here this code or using a switch ?
(in terms of performance btw)
A switch statement with adjacent numbers are often optimized to a function pointer look-up table internally.
Historically, compilers were bad at this and function pointer tables were always faster back in the days. Nowadays performance shouldn't be an argument for either version. In fact, one drawback with a manual function pointer table is that the compiler won't be able to inline the functions, something it can otherwise do when optimizing a switch.
So you shouldn't use the function pointer version because it is faster/slower, but rather because it can improve readability and maintenance of the code.
It is for example common practice to use such function pointer tables when implementing finite state machines. Complex switch statements on the other hand, are hard to read and there's various quirks with the syntax, such as the missing break bug etc.
Finally, you can improve the readability of your code if you write like this instead:
typedef void operation_t (int op1, int op2); // function type
operation_t* const op_array[] = {add, subtract, multiply}; // read-only function pointer table
op_array[i](a, b); // call specific function

Is there a way to jump to a line defined by a variable in C?

So, I have this program, where I store the line number in a variable, using
int x = __LINE__;
The value of x can keep changing.
Is it possible to jump from an arbitrary line to the one given by x, using goto or any other keyword in C?
I'm looking for something like
'keyword' x;
where the program shifts to a line defined by the variable x.
Is there a workaround if this is not possible?
The GCC compiler supports, as an extension, using labels as values so that you can work with them in a way that resembles what you're after.
It allows you to do:
void *ptr = &&label;
label:
and then
goto *ptr;
to jump to label.
This is typically useful inside the core of a virtual machine, and can of course lead to horrible spaghetti. Also, again, it's a GCC extension (also supported by Clang, I think).
NO it's not possible, one possible way to achieve something similar is to define a variable as a function pointer and once you have set the variable to
the correct function you call it.
int foo(int x) {
return x+x;
}
int (*func) (int);
func = foo;
int r = func(3);
That is possible but very painful. Suppose you have a program like this:
instruction1;
instruction2;
...
instructionn;
then you can rewrite it as:
jump:
switch(x) {
case 1:
instruction1;
case 2:
instruction2;
...
case n:
instructionn;
}
You may then insert something like:
jump:
switch(x) {
case 1:
instruction1;
case 2:
instruction2;
...
case <something>:
x = <number>;
goto jump;
...
case n:
instructionn;
}
Of course you will then encounter some problems encoding blocks like switch in such a schema, but it is always possible to translate it in this given form (not the place here to explain how). So depending on what you really have to do, I may not worth the effort.

Is it possible for a c compiler to transform an 'if-elseif' bloc into a 'switch' bloc to optimize the code?

Is it possible for a c compiler to transform an 'if-elseif' bloc into a 'switch' bloc to optimize the code ?
The following code :
if ( a == 1 ) {
bloc1
} else if ( a == 2 ) {
bloc2
} else if ( ... ) {
....
} else if ( a == n ) {
bloc n
}
during compilation is transformed to :
switch(a) {
case 1:
bloc1
break;
case 2:
bloc2
break;
...
case n:
blocn
break;
}
If it is possible every time it is feasible, is there again an advantage of 'if...elseif' blocs on 'switch' blocs ?
A compiler translates C code to machine code. On assembler level, there is no such thing as if, else or switch. There are just conditional branches and non-conditional branches.
So, no, the compiler will never do anything like what you are suggesting, because an if-else that can be replaced by a switch will already result in identical machine code, no matter which one you wrote. There is no middle "convert C to C" step.
For this reason, switch is kind of an obscure language feature, since it is in theory completely redundant. It is subjective whether a switch results in more readable or less readable code. It can do either, on a case-by-case basis.
Special case:
There exists a common optimization of switch statements that the compiler can do when all the case labels are adjacent integer constants, and that is to replace the whole switch with an array of function pointers. It can then simply use the switch condition as array index to determine which function to call. No comparisons needed. This is quite a radical optimization, because it removes numerous comparisons and thereby speeds up the code, improves branch prediction, etc.
The very same optimization is possible if you have a chain of if - else if, like so:
if(n==0)
{ }
else if(n==1)
{ }
else if(n==2)
{ }
...
This can also get optimized into an array of function pointers, just like if it were written as a switch.
A c compiler can make any optimisations it likes, so long as the program intent is not altered in any way.
Noting that a switch can only occur on integral types, the conversion to a switch in your case does appear to be optimal. Trust your optimiser to make such a transformation if appropriate. You can always inspect the output assembly to verify.
In case you've never heard about the "as-if" rule: here it is. That means, the compiler is allowed to migrate if to switch in certain occasions, yes.
switch should be used whenever possible; it gives the compiler more information about the type of data parsed and enables it to construct something like hash tables.
if should be used when switch cannot be used. That's as easy as it gets.

What is the most elegant way to loop TWICE in C

Many times I need to do things TWICE in a for loop. Simply I can set up a for loop with an iterator and go through it twice:
for (i = 0; i < 2; i++)
{
// Do stuff
}
Now I am interested in doing this as SIMPLY as I can, perhaps without an initializer or iterator? Are there any other, really simple and elegant, ways of achieving this?
This is elegant because it looks like a triangle; and triangles are elegant.
i = 0;
here: dostuff();
i++; if ( i == 1 ) goto here;
Encapsulate it in a function and call it twice.
void do_stuff() {
// Do Stuff
}
// .....
do_stuff();
do_stuff();
Note: if you use variables or parameters of the enclosing function in the stuff logic, you can pass them as arguments to the extracted do_stuff function.
If its only twice, and you want to avoid a loop, just write the darn thing twice.
statement1;
statement1; // (again)
If the loop is too verbose for you, you can also define an alias for it:
#define TWICE for (int _index = 0; _index < 2; _index++)
This would result into that code:
TWICE {
// Do Stuff
}
// or
TWICE
func();
I would only recommend to use this macro if you have to do this very often, I think else the plain for-loop is more readable.
Unfortunately, this is not for C, but for C++ only, but does exactly what you want:
Just include the header, and you can write something like this:
10 times {
// Do stuff
}
I'll try to rewrite it for C as well.
So, after some time, here's an approach that enables you to write the following in pure C:
2 times {
do_something()
}
Example:
You'll have to include this little thing as a simple header file (I always called the file extension.h). Then, you'll be able to write programs in the style of:
#include<stdio.h>
#include"extension.h"
int main(int argc, char** argv){
3 times printf("Hello.\n");
3 times printf("Score: 0 : %d\n", _);
2 times {
printf("Counting: ");
9 times printf("%d ", _);
printf("\n");
}
5 times {
printf("Counting up to %d: ", _);
_ times printf("%d ", _);
printf("\n");
}
return 0;
}
Features:
Simple notation of simple loops (in the style depicted above)
Counter is implicitly stored in a variable called _ (a simple underscore).
Nesting of loops allowed.
Restrictions (and how to (partially) circumvent them):
Works only for a certain number of loops (which is - "of course" - reasonable, since you only would want to use such a thing for "small" loops). Current implementation supports a maximum of 18 iterations (higher values result in undefined behaviour). Can be adjusted in header file by changing the size of array _A.
Only a certain nesting depth is allowed. Current implementation supports a nesting depth of 10. Can be adjusted by redefining the macro _Y.
Explanation:
You can see the full (=de-obfuscated) source-code here. Let's say we want to allow up to 18 loops.
Retrieving upper iteration bound: The basic idea is to have an array of chars that are initially all set to 0 (this is the array counterarray). If we issue a call to e.g. 2 times {do_it;}, the macro times shall set the second element of counterarray to 1 (i.e. counterarray[2] = 1). In C, it is possible to swap index and array name in such an assignment, so we can write 2[counterarray] = 1 to acchieve the same. This is exactly what the macro times does as first step. Then, we can later scan the array counterarray until we find an element that is not 0, but 1. The corresponding index is then the upper iteration bound. It is stored in variable searcher. Since we want to support nesting, we have to store the upper bound for each nesting depth separately, this is done by searchermax[depth]=searcher+1.
Adjusting current nesting depth: As said, we want to support nesting of loops, so we have to keep track of the current nesting depth (done in the variable depth). We increment it by one if we start such a loop.
The actual counter variable: We have a "variable" called _ that implicitly gets assigned the current counter. In fact, we store one counter for each nesting depth (all stored in the array counter. Then, _ is just another macro that retrieves the proper counter for the current nesting depth from this array.
The actual for loop: We take the for loop into parts:
We initialize the counter for the current nesting depth to 0 (done by counter[depth] = 0).
The iteration step is the most complicated part: We have to check if the loop at the current nesting depth has reached its end. If so, we have do update the nesting depth accordingly. If not, we have to increment the current nesting depth's counter by 1. The variable lastloop is 1 if this is the last iteration, otherwise 0, and we adjust the current nesting depth accordingly. The main problem here is that we have to write this as a sequence of expressions, all separated by commata, which requires us to write all these conditions in a very non-straight-forward way.
The "increment step" of the for loop consists of only one assignment, that increments the appropriate counter (i.e. the element of counter of the proper nesting depth) and assigns this value to our "counter variable" _.
What about this??
void DostuffFunction(){}
for (unsigned i = 0; i < 2; ++i, DostuffFunction());
Regards,
Pablo.
What abelenky said.
And if your { // Do stuff } is multi-line, make it a function, and call that function -- twice.
Many people suggest writing out the code twice, which is fine if the code is short. There is, however, a size of code block which would be awkward to copy but is not large enough to merit its own function (especially if that function would need an excessive number of parameters). My own normal idiom to run a loop 'n' times is
i = number_of_reps;
do
{
... whatever
} while(--i);
In some measure because I'm frequently coding for an embedded system where the up-counting loop is often inefficient enough to matter, and in some measure because it's easy to see the number of repetitions. Running things twice is a bit awkward because the most efficient coding on my target system
bit rep_flag;
rep_flag = 0;
do
{
...
} while(rep_flag ^= 1); /* Note: if loop runs to completion, leaves rep_flag clear */
doesn't read terribly well. Using a numeric counter suggests the number of reps can be varied arbitrarily, which in many instances won't be the case. Still, a numeric counter is probably the best bet.
As Edsger W. Dijkstra himself put it : "two or more, use a for". No need to be any simpler.
Another attempt:
for(i=2;i--;) /* Do stuff */
This solution has many benefits:
Shortest form possible, I claim (13 chars)
Still, readable
Includes initialization
The amount of repeats ("2") is visible in the code
Can be used as a toggle (1 or 0) inside the body e.g. for alternation
Works with single instruction, instruction body or function call
Flexible (doesn't have to be used only for "doing twice")
Dijkstra compliant ;-)
From comment:
for (i=2; i--; "Do stuff");
Use function:
func();
func();
Or use macro (not recommended):
#define DO_IT_TWICE(A) A; A
DO_IT_TWICE({ x+=cos(123); func(x); })
If your compiler supports this just put the declaration inside the for statement:
for (unsigned i = 0; i < 2; ++i)
{
// Do stuff
}
This is as elegant and efficient as it can be. Modern compilers can do loop unrolling and all that stuff, trust them. If you don't trust them, check the assembler.
And it has one little advantage to all other solutions, for everybody it just reads, "do it twice".
Assuming C++0x lambda support:
template <typename T> void twice(T t)
{
t();
t();
}
twice([](){ /*insert code here*/ });
Or:
twice([]()
{
/*insert code here*/
});
Which doesn't help you since you wanted it for C.
Good rule: three or more, do a for.
I think I read that in Code Complete, but I could be wrong. So in your case you don't need a for loop.
This is the shortest possible without preprocessor/template/duplication tricks:
for(int i=2; i--; ) /*do stuff*/;
Note that the decrement happens once right at the beginning, which is why this will loop precisely twice with the indices 1 and 0 as requested.
Alternatively you can write
for(int i=2; i--; /*do stuff*/) ;
But that's purely a difference of taste.
If what you are doing is somewhat complicated wrap it in a function and call that function twice? (This depends on how many local variables your do stuff code relies on).
You could do something like
void do_stuff(int i){
// do stuff
}
do_stuff(0);
do_stuff(1);
But this may get extremely ugly if you are working on a whole bunch of local variables.
//dostuff
stuff;
//dostuff (Attention I am doing the same stuff for the :**2nd** time)
stuff;
First, use a comment
/* Do the following stuff twice */
then,
1) use the for loop
2) write the statement twice, or
3) write a function and call the function twice
do not use macros, as earlier stated, macros are evil.
(My answer's almost a triangle)
What is elegance? How do you measure it? Is someone paying you to be elegant? If so how do they determine the dollar-to-elegance conversion?
When I ask myself, "how should this be written," I consider the priorities of the person paying me. If I'm being paid to write fast code, control-c, control-v, done. If I'm being paid to write code fast, well.. same thing. If I'm being paid to write code that occupies the smallest amount of space on the screen, I short the stock of my employer.
jump instruction is pretty slow,so if you write the lines one after the other,it would work faster,than writing a loop. but modern compilers are very,very smart and the optimizations are great (if they are allowed,of course). if you have turned on your compiler's optimizations,you don't care the way,you write it - with loop or not (:
EDIT : http://en.wikipedia.org/wiki/compiler_optimizations just take a look (:
Close to your example, elegant and efficient:
for (i = 2; i; --i)
{
/* Do stuff */
}
Here's why I'd recommend that approach:
It initializes the iterator to the number of iterations, which makes intuitive sense.
It uses decrement over increment so that the loop test expression is a comparison to zero (the "i;" can be interpreted as "is i true?" which in C means "is i non-zero"), which may optimize better on certain architectures.
It uses pre-decrement as opposed to post-decrement in the counting expression for the same reason (may optimize better).
It uses a for loop instead of do/while or goto or XOR or switch or macro or any other trick approach because readability and maintainability are more elegant and important than clever hacks.
It doesn't require you to duplicate the code for "Do stuff" so that you can avoid a loop. Duplicated code is an abomination and a maintenance nightmare.
If "Do stuff" is lengthy, move it into a function and give the compiler permission to inline it if beneficial. Then call the function from within the for loop.
I like Chris Case's solution (up here), but C language doesn't have default parameters.
My solution:
bool cy = false;
do {
// Do stuff twice
} while (cy = !cy);
If you want, you could do different things in the two cycle by checking the boolean variable (maybe by ternary operator).
void loopTwice (bool first = true)
{
// Recursion is your friend
if (first) {loopTwice(false);}
// Do Stuff
...
}
I'm sure there's a more elegant way, but this is simple to read, and pretty simply to write. There might even be a way to eliminate the bool parameter, but this is what I came up with in 20 seconds.

what is the alternate way of doing function of switch-case (and if-else) in c?

what is the alternate way of doing function of switch-case (and if-else) in c?
Function pointers are one alternative. Consider the following snippet that calls a function through a function pointer array:
#include <stdio.h>
void fn0(int n) { printf ("fn0, n = %d\n",n); }
void fn1(int n) { printf ("fn1, n = %d\n",n); }
void fn2(int n) { printf ("fn2, n = %d\n",n); }
void fn3(int n) { printf ("fn3, n = %d\n",n); }
static void (*fn[])(int) = {fn0, fn1, fn2, fn3};
int main(void) {
int i;
for (i = 0; i < 4; i++)
fn[i](10-i);
return 0;
}
This generates:
fn0, n = 10
fn1, n = 9
fn2, n = 8
fn3, n = 7
This sort of construct makes it very easy to implement things such as finite state machines where, instead of a massive switch statement or near-unmanageable nested if's, you can just use an integer state variable to index into an array of function pointers.
You could always use gotos... :-p
Function pointers and a semi implementation of the strategy pattern :)
.. though youll need some logic to determine which function to call
There are several different ways to handle conditional branch-and-switch scenarios in C.
The typical patterns, which you yourself mention, are switch( ) statements and if/else if/else groups. However, sometimes these flow control constructs are not the best choice for certain problems. Specifically cases such as:
High performance branching over a large domain
Branching on value domains only known at runtime
Changing the branch paths at runtime based on other conditions
In these cases, there are two patterns that I find helpful:
The Strategy pattern with a direct dispatch
The Strategy pattern with a chained dispatch
In the first approach, you map each value from your domain to a collection of function pointers. Each function handles a particular case (value) from your domain. This allows you to "jump" directly to the right handler for a particular case. This pattern works well when each case is separated from all the others and there is little or no overlapping logic.
In the second approach, you chain all of the dispatch methods together - and call each of them for all cases. Each dispatched method decides if it handles the case or not, and either returns immediately or performs some processing. This pattern is useful when there is overlap between the responsibilities of some of the handlers. It is somewhat less performant, since multiple handlers are invoked, and each decides whether it needs to perform its processing. However, this is one of the easier ways to deal with overlapping logic - the kind you could normally handle in a switch() statement with fall through (or jump) conditions.
You should only use one of these techniques if the problem really requires it, since they are less obvious to future developers and can introduce unnecessary complexity and maintenance problems if implemented poorly. It also makes your code more difficult to understand, over more common constructs like switch or if/else.

Resources