Ir para o conteúdo
  • Revista PROGRAMAR: Já está disponível a edição #60 da revista programar. Faz já o download aqui!

RafaelOliveira

Tempo de execução de funções em C

Mensagens Recomendadas

RafaelOliveira

Boas pessoal,

Estou a tentar otimizar um projecto em C, so que tenho uma duvida:

posso calcular o tempo do projecto todo fazendo "time ./nomeProjecto" no terminal, contudo existe alguma maneira de saber quanto tempo gasta cada função desse mesmo projecto, para ver onde gasta mais tempo?

Agradeço desda ja a disponibilidade

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
KiNgPiTo

Podes usar o clock da tua máquina para calcular esse tempo:


#include <time.h>

definição da tua função {

clock_t ini = clock(); // guardas o inicial

 // Código da função

 // Mostra a contagem do clock actual menos o valor inicial.. Divides pelo tempo que cada ciclo demora em segundos para obteres o tempo total em segundos
printf("\nFuncao executou em %f segundos\n", ((double)clock() - ini) / CLOCKS_PER_SEC);

}

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
pmg

Eu costumo usar o profiler gprof (exemplo abaixo).

Outra opcao é meteres o programa no debugger e examinares o call stack algumas vezes. A função que mais vezes está no topo é a função que gasta mais tempo.

Podes ainda escrever código para medir o tempo de cada função, mas isso implica alterar o código fonte.

Podes usar o clock da tua máquina para calcular esse tempo:

Correcto.

Mas o clock tem uma resolução pequena: para obteres resultados usaveis com programas 'rápidos' precisas de correr o programa milhões de vezes.

Tendo um sistema que suporta POSIX, é mais preciso usar as funções clock_*. Windows também tem funções que calculam o tempo com grande resolução, mas não as sei de cor -- e não tou para pesquisar :)


Exemplo do gprof com o seguinte codigo para calcular a soma de digitos dum numero

/* soma de digitos */

#include <stdio.h>

unsigned um(unsigned k) {
 /* converte para string */
 char tmp[1000], *p;
 unsigned val = 0;

 sprintf(tmp, "%d", k);
 p = tmp;
 while (*p) {
   val += *p - '0';
   p++;
 }
 return val;
}

unsigned dois(unsigned k) {
 /* divisoes sucessivas */
 unsigned val = 0;
 while (k) {
   val += k % 10;
   k /= 10;
 }
 return val;
}

int main(void) {
 unsigned k;
 for (k = 0; k < 100000; k++) {
   if (um(k) != dois(k)) printf("erro para o valor %d.\n", k);
 }
 return 0;
}

Compilei com o gcc, sem optimizacoes e com a opcao de gerar informacao para o gprof

$ gcc -std=c89 -pedantic -Wall -Werror -O0 -pg sod.c

Corro o programa para gerar informações para o profiler

$ ./a.out

E agora, que já tenho o ficheiro gmon.out, posso chamar o profiler e estudar o resultado

$ gprof
Flat profile:

Each sample counts as 0.01 seconds.
no time accumulated

 %   cumulative   self              self     total
time   seconds   seconds    calls  Ts/call  Ts/call  name
100.95      0.01     0.01   100000   100.95   100.95  um
 0.00      0.01     0.00   100000     0.00     0.00  dois

%         the percentage of the total running time of the
time       program used by this function.

... ...

                    Call graph (explanation follows)


granularity: each sample hit covers 2 byte(s) no time propagated

index % time    self  children    called     name
               0.01    0.00  100000/100000      main [2]
[1]    100.0    0.01    0.00  100000         um [1]
-----------------------------------------------
                                                <spontaneous>
[2]    100.0    0.00    0.01                 main [2]
               0.01    0.00  100000/100000      um [1]
               0.00    0.00  100000/100000      dois [3]
-----------------------------------------------
               0.00    0.00  100000/100000      main [2]
[3]      0.0    0.00    0.00  100000         dois [3]
-----------------------------------------------

This table describes the call tree of the program, and was sorted by
the total amount of time spent in each function and its children.

... ... ... ...

Donde se pode facilmente ver que a funcao um() ocupa o tempo todo :)

Editado por pmg

What have you tried?

Não respondo a dúvidas por PM

A minha bola de cristal está para compor; deve ficar pronta para a semana.

Torna os teus tópicos mais atractivos e legíveis usando a tag CODE para colorir o código!

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
RafaelOliveira

Eu costumo usar o profiler gprof (exemplo abaixo).

Obrigado pela ajuda, contudo, quando faço:

"gprof projecto > projecto.tempo" no terminal do linux, da-me este erro:

"gmon.out: No such file or directory"

e eu compilei da seguinte forma: "gcc -o projectoLI -pg projectoLI.c"

Sabes se preciso de instalalar alguma coisa ou estou a fazer alguma coisa de mal?

Editado por pmg
nao era preciso o quote todo

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
pmg

Tens que correr o programa compilado com a opção -pg para gerar o gmon.out.

Faz

$ gcc -Wall -Werror -o projectoLI -pg projectoLI.c

$ ./projectoLI

$ gprof > projecto.tempo

Atenção que o programa demora muito mais tempo a executar quando compilado com -pg

Editado por pmg

What have you tried?

Não respondo a dúvidas por PM

A minha bola de cristal está para compor; deve ficar pronta para a semana.

Torna os teus tópicos mais atractivos e legíveis usando a tag CODE para colorir o código!

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!

Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.

Entrar Agora

×

Aviso Sobre Cookies

Ao usar este site você aceita os nossos Termos de Uso e Política de Privacidade. Este site usa cookies para disponibilizar funcionalidades personalizadas. Para mais informações visite esta página.