Simple code performance improvement in C

Asked

Viewed 103 times

3

I had a proof that the question was :

Cosiderando that the periods of history are four:

(1) period prior to 4000 BC;

(2) from 3999 BC to 476 AD;

(3) from 477 AD to 1789 AD; and

(4) after 1790 AD.

Note that BC corresponds to before Christ, and AD corresponds to after Christ, and the birthmark of Christ is the year 0 (zero).

Write function that has as input parameters, the year and reference as to the Christian era, and return the number corresponding to the respective period of history: 1,2, 3 or 4. Then read 3 pairs of year and reference to the Christian era and identify the most recent (largest). the output format is : 3 pairs of year and reference to the Christian era, each in a separate line.

I did the code on the test and then submitted it to a website where I was evaluating the execution time, and other students did the same. My code made in C was not the fastest, others did in C and had a better execution time, so I would like to know how to improve the execution time of this code, where I am missing, if there is any redundancy, to be able to make better codes, the code is as follows::

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(){

char buffer1[8],buffer2[8],buffer3[8],buffer[8];

int Ano,i,space,Anos[3],cont=0;

char letra,letras[4];

char st_int[5];

//--------------------------------------------------------------------------
gets(buffer1);
gets(buffer2);          //RECEBE OS DADOS
gets(buffer3);
//--------------------------------------------------------------------------
 //------------------------------------------------------------------------   
inicio:
if(cont==0)strcpy(buffer,buffer1);
else if(cont==1)strcpy(buffer,buffer2);
else strcpy(buffer,buffer3);
for(i=0;i<8;i++){
space=buffer[i];                            //TRATA OS DADOS DA ENTRADA
if(space == 32){
    letra=buffer[i+1];
    st_int[i]='\0'; Ano=atoi(st_int);//printf("Ano=!%d!\n",Ano);
    break;
    }
st_int[i]=buffer[i];
}

if(cont<=2){
    letras[cont]=letra; Anos[cont]=Ano;
cont++;
if(cont<=2)goto inicio;
}
letras[cont]='\0';
//--------------------------------------------------------------------------
//--------------------------------------------------------------------------
for(i=0;i<=2;i++){
    //printf("entrou\n");
    if(letras[i] == 'a'){
        if(Anos[i]>4000){
            Anos[i]=1;continue;
            }                     //VERIFICA EM QUAL ERA OS ANOS SE ENCAIXAM
        if(Anos[i]<=3999){
            Anos[i]=2;continue;            
        }
    }
    if(letras[i]=='d'){
        if((Anos[i]>=0) && (Anos[i]<=476)){
            Anos[i]=2;continue;
        }
        if((Anos[i]>=477) && (Anos[i]<=1789)){
            Anos[i]=3;continue;
        }
        if(Anos[i]>=1790){
            Anos[i]=4;continue;
        }
    }
    }
//------------------------------------------------------------------------
//------------------------------------------------------------------------
if(Anos[0]>Anos[1])
    cont=Anos[0];                     //VERIFICA QUAL O MAIOR VALOR DA ERA
else
    cont=Anos[1];
if(Anos[1]>Anos[2])
    cont=Anos[1];
else
    cont=Anos[2];
//------------------------------------------------------------------------
printf("\n%d",cont);  //MOSTRA O RESULTADO FINAL

system("PAUSE");
return 0;
    }

I appreciate any hint/criticism/advice to improve the performance of this code and the next ones I will do.

  • 4

    Well, for starters, all calls from strcpy spend precious time unnecessarily. Try to declare buffer as char *buffer and make buffer = buffer3 (for example) instead of copying. You’ll already see some improvement. Another thing: the line with letra=buffer[i+1]; has a potential memory invasion, when the i is equal to 7 (that is, if by any chance there is a space in the last position).

  • 4

    When you say the performance was worse, how many percent are we talking about? I didn’t see anything screaming inefficient in your code at most I think you could avoid the 3 strcpy using references/pointers instead (have you studied pointers?). The rest is micro-optimization, I don’t know if it’s worth heating up with this. By the way, that system("PAUSE") in the end does not interfere with the execution time analysis, certain?

  • I hadn’t thought about this way of using pointers to replace strcpy that you talked about, although I already know pointers and have used it in some cases without even realizing that I could do it. It was really helpful, thank you.

1 answer

2

Follows a very efficient solution to the problem:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>


int parse_data( const char * str )
{
    int ano;

    ano = atoi(str);

    if( ano == 0 )
        return 2;

    if( strchr( str, 'a' ) )
    {
        if( ano > 4000 )
            return 1;
        else    
            return 2;
    }

    if( strchr( str, 'b' ) )
    {
        if( ano <= 476 )
            return 2;

        if( (ano >= 477) && (ano <= 1789) )
            return 3;

        if( ano > 1789 )
            return 4;
    }

    return -1;
}


int main( int argc, char * argv[] )
{
    int ret;
    char data[ 16 ];

    printf("Data: ");
    fgets( data, sizeof(data), stdin );

    ret = parse_data( data );

    printf("\nCodigo: %d\n", ret );

    return 0;
}

/* fim-de-arquivo */

I hope it helps!

  • I thought it was good how you did it in such a succinct way, but how the function strchr() does not decrease the performance since it is making another function call?

Browser other questions tagged

You are not signed in. Login or sign up in order to post.