Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: NOB2014 en 3 Abril 2016, 21:49 pm



Título: Medir velocidad de ejecución de un programa en lenguaje C.-
Publicado por: NOB2014 en 3 Abril 2016, 21:49 pm
Hola, gente.
Esta vez los molesto por poco, me podrían decir que tengo que agregar a mi código para medir el tiempo que tarda en ejecutarse, busqué en foros y lo que intené no funcionó. -
Es probable que me quieran dar un tirón de orejas por tratar de reinventar la rueda, pero créanme que es tan solo para practicar con punteros y de paso cotejarlo con el método de la burbuja y saber que es más rápido si un doble for o un bucle while. -

Código
  1. #include <stdio.h>
  2.  
  3. void ordenar(size_t *ptrV, size_t elementos);
  4. void mostrar(size_t *ptrV, size_t elementos);
  5.  
  6. int main( void ){
  7. size_t vector[] = {99, 8, 13, 6, 104, 40, 7, 2, 1}, *ptrV = vector;
  8. static size_t elementos = sizeof (vector) / sizeof (size_t);
  9.  
  10. ordenar(ptrV, elementos);
  11. mostrar(ptrV, elementos);
  12.  
  13. return 0;
  14. }
  15.  
  16. void ordenar(size_t *ptrV, size_t elementos){
  17. size_t i, tmp = 0;
  18.  
  19. while(1){
  20. if( *(ptrV+i) >  *(ptrV+(i+1)) ){
  21. tmp = *(ptrV+i);
  22. *(ptrV+i) = *(ptrV+(i+1));
  23. *(ptrV+(i+1)) = tmp;
  24. }
  25. if( i+1 == elementos ){
  26. if( tmp == 0) break;
  27. else{tmp = 0; i = -1;}
  28. }
  29. i++;
  30. }
  31. }
  32.  
  33. void mostrar(size_t *ptrV, size_t elementos){
  34. size_t i;
  35.  
  36. for( i = 0; i < elementos; i++ )
  37. printf( " %u", *(ptrV+i) );
  38. }

Desde ya muchas gracias. -

Saludo.
Daniel

(http://i67.tinypic.com/21m9n3t.png)


Título: Re: Medir velocidad de ejecución de un programa en lenguaje C.-
Publicado por: MAFUS en 3 Abril 2016, 22:15 pm
Si usas Unix o derivado usa el comando time. Suponiendo que tu programa se llame 'mi_programa'
escribe en el shell
Código
  1. time ./mi_programa


Título: Re: Medir velocidad de ejecución de un programa en lenguaje C.-
Publicado por: ivancea96 en 3 Abril 2016, 22:36 pm
Código
  1. #include <time.h>
  2. #include <stdio.h>
  3.  
  4. int main(){
  5.    clock_t cl = clock();
  6.    // Programa
  7.    cl = clock()-cl;
  8.    printf("%i", (cl*1000)/CLOCKS_PER_SEC);
  9. }


Título: Re: Medir velocidad de ejecución de un programa en lenguaje C.-
Publicado por: NOB2014 en 3 Abril 2016, 23:06 pm
Ivancea96, cuando corro lo que me sugeriste agregar me pasa esto:

(http://i63.tinypic.com/fnuws9.png)

compila a la perfección solo que cambie el %i por %li (me daba error).-

Daniel.



MAFUS.
Lo tuyo funciona solo que no se cierra el programa hasta apretar Enter por lo tanto en segundos el tiempo tomado no es tan preciso. -
En cuanto a Windows el que dejo a continuación, funciona (no lo verifique, pero debe ser muy parecido al de ivancea96 ) como lo posteo, pero si lo aplico al programa me hace exactamente lo mismo que al principio. -
desconozco que efecto extraño produce el programa que ordena que si le agrego esas pocas líneas revienta, seguiremos investigando, igual espero que alguien se ilumine y pueda hallar la solución. -

Código
  1. #include <stdio.h>
  2. #include <time.h>
  3.  
  4. int main( void )
  5. {
  6. long int i=0;
  7. clock_t comienzo;
  8.  
  9. comienzo=clock();
  10. for( i=0; i<10000; i++ ){
  11. printf("*");
  12. }
  13.  
  14. printf( "\n Sgundos transcurridos.....: %f s\n", (clock()-comienzo)/(double)CLOCKS_PER_SEC );
  15.  
  16. return 0;
  17. }

Daniel.


Título: Re: Medir velocidad de ejecución de un programa en lenguaje C.-
Publicado por: ivancea96 en 4 Abril 2016, 11:50 am
Me funciona correctamente. ¿Cuál es el código que te falla, y qué código de error lanza?


Título: Re: Medir velocidad de ejecución de un programa en lenguaje C.-
Publicado por: NOB2014 en 4 Abril 2016, 14:14 pm
Hola.
Citar
¿Cuál es el código que te falla?
Cuando le agrego las líneas que me sugeriste.
Citar
¿qué código de error lanza?
Al compilar ninguno, al ejecutar no muestra nada y aparece el mensaje que postee anteriormente. -
Cuando decís que te funciona correctamente, te referís a que ¿lo estás corriendo dentro del programa mío o con algún código diferente?. -

Saludos.


Título: Re: Medir velocidad de ejecución de un programa en lenguaje C.-
Publicado por: class_OpenGL en 4 Abril 2016, 15:04 pm
El problema está en la función "ordenar". No has inicializado la variable "i", por lo que al principio del while esta variable tiene un valor basura, que por casualidad, no te da error cuando pones solo tu código pero si que da error cuando fusionamos tu código con el de contar el tiempo. Repito, es casualidad que al principio no diera error


Título: Re: Medir velocidad de ejecución de un programa en lenguaje C.-
Publicado por: NOB2014 en 4 Abril 2016, 17:11 pm
Hola,  class_OpenGL.
Efectivamente, esa variable era la causante del error, cuando cambie el bucle for por el while no lo tube en cuenta. -
En la función printf efectué 2 cambios y quedo así (de lo contrario me daba errores):

Código
  1. printf("\n\n Milesegundos transcurridos.....:%f", (cl*1000)/(double)CLOCKS_PER_SEC);

%f y (double)

Por último ¿es coherente que me de el resultado con el signo menos?
-98.000000
-95.000000

Saludos.
Daniel


Título: Re: Medir velocidad de ejecución de un programa en lenguaje C.-
Publicado por: ivancea96 en 4 Abril 2016, 17:29 pm
No, no lo es. Si vas a trabajar con milisegundos, te recomiendo tratarlo como entero. En Windows, no tendrás microsegundos.

Luego, asegúrate de haber hecho clock()-cl y no al revés.


Título: Re: Medir velocidad de ejecución de un programa en lenguaje C.-
Publicado por: class_OpenGL en 4 Abril 2016, 20:23 pm
He probado el programa y me salen 0 milisegundos (recuerda que solo mides milisegundos, y estos se truncan), ninguna cifra negativa.


Título: Re: Medir velocidad de ejecución de un programa en lenguaje C.-
Publicado por: NOB2014 en 4 Abril 2016, 23:24 pm
Hola a todos.
Voy a exponer el código y como lo implemente para que me digan si es correcto porque me quedan dudas con el resultado, por Ej. 4294967199, ¿estos son milisegundos y 4.30.... segundos?.-

En cuanto a Linux, se puede poner esta línea para que la salida vaya a un archivo de texto. -
>> (time ls) 2> salida.txt

Código
  1. int main( void ){
  2. size_t vector[] = {99, 8, 13, 6, 10, 40, 7, 2, 1,74}, *ptrV = vector;
  3. static size_t elementos = sizeof (vector) / sizeof (size_t);
  4. clock_t cl = clock();
  5.  
  6. ordenar(ptrV, elementos);
  7. mostrar(ptrV, elementos);
  8.  
  9. cl = clock() - cl;
  10.  
  11. printf("\n\n %lu", (cl*1000)/CLOCKS_PER_SEC);
  12.  
  13. return 0;
  14. }
Saludos.
Daniel


Título: Re: Medir velocidad de ejecución de un programa en lenguaje C.-
Publicado por: class_OpenGL en 5 Abril 2016, 00:00 am
No, el resultado está en milisegundos. Deduzco que por alguna razón te está saliendo un número negativo en la operación "cl = clock() - cl;", pero al interpretar ese número negativo como un entero sin signo, te sale ese número. Si en vez de mostrarlo como un entero sin signo lo mostraras con signo, te saldría -97 ms...

No sé por qué razón te sale un tiempo negativo... Prueba a compilar con otro compilador. Yo he compilado el código tal y como tu lo tienes y me salen resultados coherentes...


Título: Re: Medir velocidad de ejecución de un programa en lenguaje C.-
Publicado por: NOB2014 en 5 Abril 2016, 18:56 pm
Hola.
Bueno a pesar de no lograr el cometido porque realmente todas las pruebas que hice no me dieron resultdo, encontré una aplicación utilizando la librería windows.h  que funciona muy bien, me gustaría colgarla aquí, pero como no conozco si es legal esto de sacar programas de una página y copiarlo en otra mejor lo dejamos ahí. -
Lo que quiero consultarles concretamente es ¿es posible generar números aleatorios sin que se repitan?  o la única manera es por cada número generado verificar si ya se encuentra en el arreglo. -

Código
  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. #include<time.h>
  4.  
  5.  
  6. void llenar( size_t *ptrNumeros );
  7. void ordenar( size_t *ptrNumeros );
  8. void mostrar( size_t *ptrNumeros );
  9. #define TAM 102
  10.  
  11. int main( int argc, char *argv[] ){
  12. size_t numeros[TAM], *ptrNumeros = numeros;
  13.  
  14. llenar( ptrNumeros );
  15. ordenar( ptrNumeros );
  16. mostrar( ptrNumeros );
  17.  
  18. return 0;
  19. }
  20.  
  21. void llenar( size_t *ptrNumeros ){
  22. size_t hora = time(NULL), i;
  23. srand(hora);
  24.  
  25. for(i = 0; i < TAM; i++){
  26. *(ptrNumeros + i) = rand()% 100 + 200;
  27. }
  28. }
  29.  
  30. void ordenar( size_t *ptrNumeros ){
  31. size_t i = 0, tmp = 0;
  32.  
  33. while(1){
  34. if( *( ptrNumeros+i) >  *(ptrNumeros+(i+1)) ){
  35. tmp = *(ptrNumeros+i);
  36. *(ptrNumeros+i) = *(ptrNumeros+(i+1));
  37. *(ptrNumeros+(i+1)) = tmp;
  38. }
  39. if( i+1 == TAM ){
  40. if( tmp == 0) break;
  41. else{tmp = 0; i = -1;}
  42. }
  43. i++;
  44. }
  45. }
  46.  
  47. void mostrar(size_t *ptrNumeros){
  48. size_t i;
  49.  
  50. for( i = 0; i < TAM; i++ ){
  51. if( i%10 == 0 ) printf( "\n" );
  52. printf( " %u", *(ptrNumeros+i) );
  53. }
  54. }

Saludos.
Daniel


Título: Re: Medir velocidad de ejecución de un programa en lenguaje C.-
Publicado por: class_OpenGL en 6 Abril 2016, 00:27 am
Podrías generar un número aleatorio guardado en el primer elemento, y cuando calcules un número aleatorio en el segundo, si este es igual al primero, generas otro número aleatorio, y así para todas las posiciones del arreglo. Es una solución relativamente sencilla, pero no sé si será la mejor porque dependes de que te salga un número aleatorio diferente (saldrá, pero no sé después de cuántas ejecuciones)


Título: Re: Medir velocidad de ejecución de un programa en lenguaje C.-
Publicado por: NOB2014 en 6 Abril 2016, 00:52 am
Hola, amigo.
Te dejo la manera que lo hice, no tarda tanto en aparecer los 100 números, Parece ser lo que me propones.

Código
  1. void llenar( size_t *ptrNumeros ){
  2. size_t hora = time(NULL), i, tmp, ok = 0;
  3. srand(hora);
  4.  
  5. for(i = 0; i < TAM; i++){
  6. do{
  7. tmp = rand()% 999 + 1 ;
  8. ok = verifica( ptrNumeros, tmp );
  9. }while(ok);
  10. *( ptrNumeros + i ) = tmp;
  11. }
  12. }
  13.  
  14. int verifica( size_t *ptrNumeros, size_t tmp ){
  15. size_t i, stop = 0;
  16.  
  17. for( i = 0; i < TAM; i++ ){
  18. if( *( ptrNumeros + i) == tmp )
  19. stop = 1;
  20. }
  21.  
  22. return stop;
  23. }

Saludos.


Título: Re: Medir velocidad de ejecución de un programa en lenguaje C.-
Publicado por: MAFUS en 6 Abril 2016, 01:16 am
Con el problema de contar los tiempos: yo he terminado de hacer este programa y me cuenta hasta los microsegundos.

Código
  1. #include <stdio.h>
  2. #include <time.h>
  3.  
  4. int main() {
  5.    time_t c=clock();
  6.    long unsigned j = 1;
  7.  
  8.    for(long unsigned i = 0; i < 1000000000; ++i) {
  9.        if(i == j) {
  10.            printf("t(%lu) = %f\n", j, (clock() - c)*1.0/CLOCKS_PER_SEC);
  11.            j *= 10;
  12.        }
  13.    }
  14.    printf("t(%lu) = %f\n", j, (clock() - c)*1.0/CLOCKS_PER_SEC);
  15.  
  16.    return 0;
  17. }


Título: Re: Medir velocidad de ejecución de un programa en lenguaje C.-
Publicado por: crack81 en 6 Abril 2016, 01:59 am
Hola : NOB2014

Tu código parase que ya funciona solo mencionaria unos detalles

Ejemplo esta linea:
Código
  1. size_t numeros[TAM], *ptrNumeros = numeros;

No es necesario crear un arreglo y luego asignárselo a un puntero. Si por ejemplo lo vas a pasar por parametro a una funcion, el cual esta declarado de esta forma:

Código
  1. void llenar( size_t *ptrNumeros )
basta con ponerlo directamente al final de cuentas un arreglo es una estructura que apunta a una dirección en resumen es un puntero

Ejemplo:

Código
  1. size_t numeros[TAM]
  2. llenar( numeros );

Otro detalle, este ya es en gustos, te aconsejaría remplazar esta forma de asignar el arreglo:
Código
  1. *(ptrNumeros + i) = rand()% 100 + 200;
Y recomendaría mejor esta:

Código
  1. ptrNumeros[i]= rand()% 100 + 200;

Las dos formas funcionan igual pero, la segunda forma hace tu código mas legible, y se hace mas a relucir cuando se aumenta el tamaño y complejidad del proyecto


Espero mis comentarios no se tomen a mal
Salutos....


Título: Re: Medir velocidad de ejecución de un programa en lenguaje C.-
Publicado por: NOB2014 en 6 Abril 2016, 15:23 pm
Hola.
MAFUS, te dejo una captura para que me digas que es lo que estoy leyendo, segundos, milesegundos. -

(http://i68.tinypic.com/wuid1x.png)

crack81, muchas pero muchas gracias por esas sugerencias no tenes una idea como se agradece de este lado, no obstante (como lo aclare al principio) lo hice con punteros porque estoy estudiando justamente punteros y estaba practicando. -

Un abrazo y muchas gracias por el tiempo que le dedicaron al tema. -
Daniel


Título: Re: Medir velocidad de ejecución de un programa en lenguaje C.-
Publicado por: class_OpenGL en 6 Abril 2016, 15:39 pm
Solo es cuestión de observación. ¿Estás usando cl/CLOCKS_PER_SEC o (cl*1000)/CLOCKS_PER_SEC? Si estás usando la primera opción, son segundos (te lo dice CLOCKS_PER_SEC), pero si estás usando la segunda  opción estás viendo milisegundos, porque estás multiplicando los segundos por 1000.


Título: Re: Medir velocidad de ejecución de un programa en lenguaje C.-
Publicado por: MAFUS en 6 Abril 2016, 15:40 pm
La unidad es el segundo: 1.000000 es 1 segundo.


Título: Re: Medir velocidad de ejecución de un programa en lenguaje C.-
Publicado por: HardForo en 16 Abril 2016, 14:26 pm
No puedo decir que este "bien" ahora pero parece ser que al menos por un factor de 100 estaba errado antes.

Código
  1. #include <stdio.h>
  2. #include <time.h>
  3.  
  4. int main( void )
  5. {
  6. long int i=0;
  7. clock_t comienzo;
  8.  
  9. comienzo=clock();
  10.  
  11. // programa
  12. for( i=0; i<5000000; i++ ){
  13. printf("*");
  14. }
  15.  
  16. printf( "\n Segundos transcurridos.....: %f s\n", 100*(clock()-comienzo)/(double)CLOCKS_PER_SEC );
  17.  
  18. return 0;
  19. }
  20.  


Segun leo en StackOverflow: "CLOCKS_PER_SEC might be defined as 1000000, depending on what options you use to compile, and thus it does not seem like a good solution."

http://stackoverflow.com/questions/5248915/execution-time-of-c-program

---
PD: realmente veo que ni siquiera es un factor multiplo de 10


Título: Re: Medir velocidad de ejecución de un programa en lenguaje C.-
Publicado por: ivancea96 en 16 Abril 2016, 14:31 pm
Eso son centisegundos, no segundos.


Título: Re: Medir velocidad de ejecución de un programa en lenguaje C.-
Publicado por: HardForo en 16 Abril 2016, 14:34 pm
Me tomé el trabajo de medir el tiempo de ejecucion del programa que posteé (o sea le subi el tiempo hasta que sea posible medirlo facilmente) y como digo...... el valor esta "en el orden" de los SEGUNDOS (correcto ahora para mi SO) pero tampoco es creo exacto (me difiere en algunos segundos)

Veo el problema como algo "grave" ya que nadie parece tener la seguridad de como es y menos cross-plataform o cross-compiler


Título: Re: Medir velocidad de ejecución de un programa en lenguaje C.-
Publicado por: ivancea96 en 16 Abril 2016, 14:54 pm
En Windows, suele ser CLOCKS_PER_SEC = 1000, y en Unix = 1000000. clock también retorna un valor acorde a estas cantidades y correcto.

1. ¿Qué valor tiene CLOCKS_PER_SEC en tu SO?
2. ¿Qué SO es?
3. ¿El valor retornado por tu clock() va en el rango de los milisegundos o de los microsegundos? ¿Otro quizás?


Título: Re: Medir velocidad de ejecución de un programa en lenguaje C.-
Publicado por: HardForo en 16 Abril 2016, 15:31 pm
Uso Windows 6.3 y si vale 1000 como dices

En fin.... me toco multiplicar por 100 como decia respecto del programa aportado aqui para que tenga algun sentido....


Título: Re: Medir velocidad de ejecución de un programa en lenguaje C.-
Publicado por: ivancea96 en 16 Abril 2016, 15:45 pm
¿Qué valor da clock()-comienzo en una diferencia aproximada de 1 segundo? En entero, sin coma flotante.


Título: Re: Medir velocidad de ejecución de un programa en lenguaje C.-
Publicado por: NOB2014 en 16 Abril 2016, 16:02 pm
Hola.
Perdón por interponerme pero el código de boctulus me da resultados correctisimos, medido con un reloj de una página de internet, correctisimos. -

Solo que lo hago como dijo MAFUS, en segundos. -

Código
  1. printf( "\n Segundos transcurridos.....: %f s\n", 1.0*(clock()-  comienzo)/(double)CLOCKS_PER_SEC );

Saludos.
Daniel


Título: Re: Medir velocidad de ejecución de un programa en lenguaje C.-
Publicado por: HardForo en 16 Abril 2016, 16:12 pm
El codigo no es mio, es la forma estandar de usar la libreria

Pero como digo en Windows el factor es de 100 (aprox) asi que creo este tipo de calculos deberian hacerse con ayuda del precompilador (#ifndef _Windows ...) al menos que se quiera solo valores relativos (mismo computador, mismo SO)

Código
  1. #include <stdio.h>
  2. #include <time.h>
  3.  
  4. #ifdef __linux__
  5.    #define TIMEFACTOR   1
  6. #elif _WIN32
  7.    #define TIMEFACTOR   100
  8. #else
  9. // definir
  10. #endif
  11.  
  12. int main( void )
  13. {
  14. long int i=0;
  15. clock_t comienzo;
  16.  
  17. comienzo=clock();
  18.  
  19. // programa
  20. for( i=0; i<1000000; i++ ){
  21. printf("*");
  22. }
  23.  
  24. printf( "\n Segundos transcurridos.....: %f s\n", TIMEFACTOR*(clock()-comienzo)/(double)CLOCKS_PER_SEC );
  25.  
  26. return 0;
  27. }
  28.  


Título: Re: Medir velocidad de ejecución de un programa en lenguaje C.-
Publicado por: ivancea96 en 16 Abril 2016, 16:39 pm
Insisto, el único "factor" es CLOCKS_PER_SEC, que para eso existe.
Multiplicar por 1000, da milisegundos. multiplicar por 100, centisegundos.

Si en tu compilador o sistema no funciona así, habrá que analizar por qué. Poner un coeficientes que cuadre no es una opción lógica.

Prueba si quieres en otro PC, en otro SO o en una máquina virtual para ver el resultado que debiera dar.


Título: Re: Medir velocidad de ejecución de un programa en lenguaje C.-
Publicado por: HardForo en 16 Abril 2016, 16:56 pm
Ivan: me parece perfecto que insistas, estoy tratando de ver porque no me concuerdan los resultados.

Siguiendo con la liberia time.h, te pido mires este codigo....... no le encuentro el fallo:

Código
  1. #include <stdio.h>
  2. #include <time.h>
  3.  
  4. int main( void )
  5. {
  6.  
  7. // solo como control adicional
  8.  time_t tiempo1 = time(0);
  9.  time_t tiempo2 = time(0);
  10.  struct tm *tini = localtime(&tiempo1);
  11.  struct tm *tfin = localtime(&tiempo2);
  12.  char output[128];
  13.  
  14.  
  15.  strftime(output,128,"%d/%m/%y %H:%M:%S",tini);
  16.  printf("%s\n",output);
  17.  
  18. // programa
  19. for(int i=0; i<40000000; i++ ){
  20. }
  21.  
  22.  strftime(output,128,"%d/%m/%y %H:%M:%S",tfin);
  23.  printf("%s\n",output);
  24.  
  25. return 0;
  26. }
  27.  

No logro muestre dos fechas-horas distintas! 

PD: quiero utilizar esto para rematar con el tema..... probando si es necesario o no un TIMEFACTOR adicional (pues en realidad quiero estar de acuerdo contigo)


Título: Re: Medir velocidad de ejecución de un programa en lenguaje C.-
Publicado por: ivancea96 en 16 Abril 2016, 17:24 pm
En todo caso:
Código
  1. #include <stdio.h>
  2. #include <time.h>
  3.  
  4. int main( void )
  5. {
  6.  
  7. // solo como control adicional
  8.  time_t tiempo1 = time(0);
  9.  struct tm *tini = localtime(&tiempo1);
  10.  char output[128];
  11.  
  12.  
  13.  strftime(output,128,"%d/%m/%y %H:%M:%S",tini);
  14.  printf("%s\n",output);
  15.  
  16. // programa
  17. for(int i=0; i<1000000000; i++ ){
  18. }
  19.  
  20.  time_t tiempo2 = time(0);
  21.  struct tm *tfin = localtime(&tiempo2);
  22.  strftime(output,128,"%d/%m/%y %H:%M:%S",tfin);
  23.  printf("%s\n",output);
  24.  
  25. return 0;
  26. }

Si llamas a time() al principio 2 veces, serán iguales.


Título: Re: Medir velocidad de ejecución de un programa en lenguaje C.-
Publicado por: HardForo en 16 Abril 2016, 21:46 pm
Me sirvió  ;D

Gracias y.... por todo!