RafaelOliveira Posted March 21, 2013 at 10:29 AM Report #499851 Posted March 21, 2013 at 10:29 AM 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
KiNgPiTo Posted March 21, 2013 at 10:55 AM Report #499858 Posted March 21, 2013 at 10:55 AM 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); }
pmg Posted March 21, 2013 at 10:59 AM Report #499859 Posted March 21, 2013 at 10:59 AM (edited) 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 🙂 Edited March 21, 2013 at 11:25 AM by 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!
RafaelOliveira Posted March 21, 2013 at 11:29 AM Author Report #499862 Posted March 21, 2013 at 11:29 AM (edited) 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? Edited March 21, 2013 at 11:34 AM by pmg nao era preciso o quote todo
pmg Posted March 21, 2013 at 11:33 AM Report #499864 Posted March 21, 2013 at 11:33 AM (edited) 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 Edited March 21, 2013 at 11:36 AM by 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!
Rui Carlos Posted March 22, 2013 at 08:52 PM Report #500070 Posted March 22, 2013 at 08:52 PM Para o pessoal que usa MacOSX (não sei se é o caso), têm um profiler excelente chamado Instruments 🙂 Rui Carlos Gonçalves
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now