Good manners for programming in C

I am currently programming my own implementation of printf , here is the code:

 int my_printf(const char *format, ...) { //Declare variable ou prog fonctionnel???? va_list args; int numberValue; unsigned int unsignedNumberValue; double doubleValue; char* stringValue; char charValue; va_start(args, format); for(int i = 0; format[i]; i++){ //This case is the most called case, so we test it first to get the //best perfs if(format[i] != '%'){ my_put_char(format[i]); }else{ if(format[i+1] == 'd' || format[i+1] == 'i'){ numberValue = va_arg(args, int); my_put_nbr(numberValue); }else if(format[i+1] == 'u'){ unsignedNumberValue = va_arg(args, unsigned int); my_put_nbr_unsigned(unsignedNumberValue); }else if(format[i+1] == 'o'){ numberValue = va_arg(args, int); my_put_nbr_base(numberValue, 2); }else if(format[i+1] == 'c'){ //char parameters are passed as integer as va_args charValue = va_arg(args, int); my_put_char(charValue); }else if(format[i+1] == 's'){ stringValue = va_arg(args, char*); my_puts(stringValue); }else if(format[i+1] == 'f'){ doubleValue = va_arg(args, double); my_put_double(doubleValue); }else if(format[i+1] == '%'){ my_put_char('%'); }else{ //error option not handled char* error = my_strcat("\nThe option you provided is not a valid option: %", &format[i + 1], 1); write(2, error, sizeof(char) * my_strlen(error)); } i++; } } va_end(args); return 0; } 

I would like to learn two things about my code:

  • I wonder if I should program the "function method" , for example, not to use a variable, but put va_args , called directly in the my_put function. But by doing this, he will allocate and free each cycle instead of one declaration (distribution), which cannot be used, and one free at the end of the function. In a large process, I believe that it is better to store the return value in a variable and then call the function function. (e.g. for strlen in very large text)
  • I would also like to know how to handle functions that can be called using different types, such as my_put_nbr in my code, can I overload them? It seems that he should have a different name.
+5
source share
1 answer

Optimizing printf for speed makes little sense, since character I / O will be the dominant runtime. Even quick formatting processing will not save you the time needed to send your characters along the way.

The only thing that may cost here is size: the size of the stack, avoiding another level of function invocation and code size, writing as few output functions as possible.

The first thing to do to optimize your code is to turn your tests into a switch. Most likely, the compiler will implement it as a table jump, which is more efficient than a bunch of tests. You can put the “most likely” formats at first, but if you can't read the user mind, it's pretty difficult to predict whether he / she would be better off displaying integers or floating or characters.

Passing a variable number of parameters is the most expensive operation, so delegating the vararg processing to each atomic formatting function will only produce more voluminous and slower code.

Instead, you'd better write your output code as built-in functions and hope that the compiler expands them to save you another level of function calls.

For the various possible sizes of the arguments, the way is to make all the values ​​as large as possible (32 or 64 bits of integers, floats or doubles, depending on what you want to support) and have a limited number of display functions (integer integers / unsigned / double, for example).
Thus, you reduce the size of the source and executable code.

0
source

All Articles