viernes, agosto 22, 2008

Gran avance

Bueno, ante la desesperación de tener que esperar más de 2 horas para obtener los primos que hay entre el número 1 y el 100.000.000 la solución ha sido convertir el programa Visual Basic a C++.

De esta forma los tiempos se han reducido un montón.

Con el límite en 100.000 tardabamos 3 segundos.
Ahora esos 9592 primos se logran en menos de 1 segundo.

Con el límite en 1.000.000 se tardaba 14 segundos. Ahora se consiguen los 78.498 primos en unos 2 segundos.

Poniendo el límite en 100.000.000, se lograban los 5.761.455 primos en 2 horas 14 minutos 58 segundos y ahora los conseguimos los 5761455 primos en 14 minutos y 26 segundos.

Cambios en el programa
El programa no lo he hecho exactamente igual. En lugar de usar formularios Windows he creado un proyecto de consola Win32. Por lo tanto no hay un cuadro de lista donde acumular los primos. Lo que he hecho es generar un fichero de texto donde se van guardando los primos que se descubren. Esto es algo que lógicamente hace el programa muchísimo más lento que si no los almacenáramos.

Para saber lo que tarda el programa en obtener esos primos he utilizado la función clock() de la librería estándar. El tiempo de ejecución se almacena al final del fichero de texto.
Lo que ocurre es que para ejecuciones rápidas de pocos segundos esta función no va del todo bien. En lugar de 1 segundo indica que ha necesitado 8 segundos. En lugar de 2 segundos indica 25. En cambio cuando la ejecución ha tardado 14 minutos y 26 segundos ha clavado el tiempo.

Como curiosidad, indicar que los 5.761.455 primos obtenidos, en el fichero de texto ocupan 55.528Kb.

Sin más hay va el programita en C++:


#include "stdafx.h"
#include
#include
using namespace std;
#include

int _tmain(int argc, _TCHAR* argv[])
{
ofstream fs("primos.txt");

clock_t clock(void);

int candidato = 5;
int pruebaDivisor;
int esPrimo;
int numPrimos = 2;
int limiteSuperior;

printf("Introduce el limite al que llegar: ");
scanf("%d",&limiteSuperior);

fs << 2 << endl;
fs << 3 << endl;
while(candidato <= limiteSuperior)
{
pruebaDivisor = 5;
esPrimo = 1;
while(pruebaDivisor * pruebaDivisor <= candidato)
{
if(candidato % pruebaDivisor == 0)
{
esPrimo = 0;
break;
}
pruebaDivisor += 2;
}
if(esPrimo == 1)
fs << candidato << endl;

candidato += 2;

pruebaDivisor = 5;
esPrimo = 1;
while(pruebaDivisor * pruebaDivisor <= candidato)
{
if((candidato % pruebaDivisor) == 0)
{
esPrimo = 0;
break;
}
pruebaDivisor += 2;
}
if(esPrimo == 1)
fs << candidato << endl;

candidato += 4;
}

fs << "Desde el inicio: " << clock()/CLK_TCK << " segundos\n";

fs.close();
cin.get();
return 0;
}


No hay comentarios: