Foros del Web » Programando para Internet » PHP »

Lentitud extrema con php

Estas en el tema de Lentitud extrema con php en el foro de PHP en Foros del Web. Hola Buenos dias amigos, les molesto nuevamente por la siguiente situacion: Tengo un programa que hace ciertas validaciones de una data que nos envian en ...
  #1 (permalink)  
Antiguo 07/10/2008, 07:44
 
Fecha de Ingreso: agosto-2008
Ubicación: Caracas
Mensajes: 51
Antigüedad: 15 años, 8 meses
Puntos: 0
Lentitud extrema con php

Hola Buenos dias amigos, les molesto nuevamente por la siguiente situacion:
Tengo un programa que hace ciertas validaciones de una data que nos envian en formato txt Vs la informacion que tenemos en nuestra BD y dependiendo de los resultados de las validaciones se etiqueta cada uno de los registros de dicho archivo en una carpeta o archivo diferente. La forma en la que manejo el programa es la siguiente:

en primer lugar hago las consultas (son 5 mssql_query) a la BD y las almaceno en memoria (esto lo hago para no tener que estar abriendo y cerrando la BD por cada valor que se vaya a validar) luego de tener ya las consultas en memoria cierro las conexiones a la BD y entro en el ciclo para empezar a validar cada uno de los items que se encuentran en el archivo txt que nos envian y dependiendo de los resultados de dichas validaciones almaceno el item en un archivo txt denominado para almacenar cada tipo de producto.

El problema que estoy presentando es el siguiente, muy claro y conciso:

Al momento de correr el programa se tarda mas de 6 horas en correr lo que me parece extremadamente lento.

Los registros que almaceno en memoria no superan los 50.000 y los registros que envian para validar en ocasiones llegan a los 40.000.

El servidor web lo tengo instalado en:
Windows XP sp2 2GBRam Pentium4
Server API Apache 2.0 Handler
PHP Version 5.2.6
La BD es windows 2003 Server (esta instalada en otro equipo)

He tratado de buscar informacion sobre lentitud en php y he conseguido informacion sobre aceleradores php los cuales segun lo encontrado son pagos, en este sentido me gustaria en primer lugar que me orientaran en cuanto a si para este programa (por demas sencillo) seria necesario la obtencion de uno de estos aceleradores o si ppor el contrario hay algun tips que me puedan dar a fin de verificar que es lo que esta pasando con el programa.

Nuevamente muchas gracias anticipada por toda la ayuda que me puedan brindar...
  #2 (permalink)  
Antiguo 07/10/2008, 08:05
 
Fecha de Ingreso: agosto-2008
Ubicación: Argentina
Mensajes: 19
Antigüedad: 15 años, 8 meses
Puntos: 0
Respuesta: Lentitud extrema con php

Hola que tal? mira lo que yo te recomiendo es que primero busques alguna falla en tu algoritmo, si tienes 5 consultas intenta de ejecutar primero una (comentando las demas) si no se cuelga despues prueba la otra y asi hasta que encuentres la que esta frenando la ejecucion, yo hice cosas en php y la verdad nunca tuve ese problemilla, pero me interesa saber y ayudarte. Yo te recomendaria eso como para ir descartando que no tengas problemas en tu algoritmo y despues seguiremos probando con otras cosas. Tienes base de datos de prueba? o sea base de datos test y base de datos de produccion?.



un abrazo
  #3 (permalink)  
Antiguo 07/10/2008, 08:10
 
Fecha de Ingreso: agosto-2008
Ubicación: Caracas
Mensajes: 51
Antigüedad: 15 años, 8 meses
Puntos: 0
Respuesta: Lentitud extrema con php

Hola Marcos, gracias por tu pronta respuesta e interes en ayudar.
El problema no radica en las consultas las mismas me las hace sin inconveniente en un lapso no mayor a 5 sg, el problema radica luego que empieza a hacer las validaciones, de hecho algo que me llama la atencion es que el programa empieza, en cierto modo, rapido pero a medida que va avanzando en las validaciones se va poniendo mas lento.
el procesador se pone en un 100% de su capacidad.

Y si, si tengo una BD de prueba
  #4 (permalink)  
Antiguo 07/10/2008, 08:24
 
Fecha de Ingreso: agosto-2008
Ubicación: Argentina
Mensajes: 19
Antigüedad: 15 años, 8 meses
Puntos: 0
Respuesta: Lentitud extrema con php

mmmm.... bueno eso cambia un poco, el algoritmo de comparacion?, mas arriba habias dicho de que guardabas los datos en memoria puede ser? en algun tipo de array? o algo de eso? si quieres y puedes quizas poniendo un poco de tu codigo de comparacion podemos llegar a ver eso, el tema es que no creo que sea php lo que si puede ser el algoritmo de comparacion y el manejo de memoria mas si dices que son 50.000 registros, tambien habria que ver si el txt lo levanta remoto o desde el mismo server.






un abrazo
  #5 (permalink)  
Antiguo 07/10/2008, 08:38
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 17 años, 11 meses
Puntos: 2135
Respuesta: Lentitud extrema con php

Exactamente, como dice marcoskp, habría que ver el proceso de lectura que haces, y como es que haces la comparación ya que el problema radica en esos puntos mas que en "acelerar" PHP.

Saludos.
  #6 (permalink)  
Antiguo 07/10/2008, 08:55
 
Fecha de Ingreso: agosto-2008
Ubicación: Caracas
Mensajes: 51
Antigüedad: 15 años, 8 meses
Puntos: 0
Respuesta: Lentitud extrema con php

Hola este vendria siendo uno de los algoritmos de comparacion, basicamente lo que estoy utilizando son if anidados dentro de bucles for.

(las variables $matriz8 y $cont las obtengo de la conexion a la bd que hago antes de entrar a este algoritmo)

Parte del codigo seria el siguiente:
//**********************************************

$archivo = file("ArchivoaValidar.txt");
$lineas = count($archivo);
for ($k=0; $k < $lineas; $k++)
{
$datosfilas = explode(",",$archivo[$k]);
$codigoprod = str_replace(" ","",$datosfilas[0]);
$lengcodigo = strlen($codigoprod);

if ($lengcodigo ==8)
{
$codigos8=$codigos8+1;
$codigopais= substr($codigoprod, 0, 3); // bcd
if ($codigopais ==899)
{
$contador1=0;
$encontradoa=0;
$encontrador=0;
for ($m=0; $m < $cont; $m++)
{
$matrizsub8= $matriz8[$m];
$matrizsub8_2=str_replace(" ","",$matrizsub8[0]);
$matrizsub8_3= $matrizsub8[1];
if ($codigoprod == $matrizsub8_2)
{
$contador1=$contador1+1;
if ($matrizsub8_3=="A")
{
$encontradoa=$encontradoa+1; $contencontradoa=$contencontradoa+1;
fwrite($encontradoatxt, $archivo[$k]);
unset($archivo[$k]);
break 1;
}
else if ($matrizsub8_3=="R")
{ $encontrador=$encontrador+1; $contencontrador=$contencontrador+1;
fwrite($encontradortxt, $archivo[$k]);
unset($archivo[$k]);
break 1;
}
}
}
if ($contador1=0)
{
$contcodnovalido=$contcodnovalido+1;
fwrite($codnovalidotxt, $archivo[$k]);
unset($archivo[$k]);
}
}
else
{
$encontradocodpais=0;
for ($i=0;$i<$cont2;$i++)
{
$matrizpaisgs1=$matrizpais[$i];
$matrizpaisgs1_2=str_replace(" ","",$matrizpaisgs1[0]);
if ($codigopais==$matrizpaisgs1_2)
{ $encontradocodpais=$encontradocodpais+1;
break 1;
}
}
if ($encontradocodpais>0)
{
$contencontradocodpais = $contencontradocodpais+1;
fwrite($encontradocodpaistxt, $archivo[$k]);
unset($archivo[$k]);
}
else
{ $contcodnovalido=$contcodnovalido+1;
fwrite($codnovalidotxt, $archivo[$k]);
unset($archivo[$k]);
}
}
}
//**********************************************

Este codigo solo valida los codigos de longitud 8, pero manteniendo la misma estructura se hacen otras validaciones para los codigos de longitud 12, 13 y 14.
El archivo que es producto de las validaciones contra la BD es cargado en el mismo servidor donde se ejecuta la pagina en la misma ruta donde esta alojada la misma.

//*******************************************
Aqui te coloco tambien la forma en la que almaceno en memoria uno de las consultas a la bd :

$conectID = mssql_connect("ejemplo","user","password");
mssql_select_db("DB_prueba");
if (!$conectID)
{
die('<h1><center>Imposible establecer conexión</center></h1>');
}
echo '<h1><center>conexion satisfactoria codigos de longitud 8</h1></center>';
$sql = "SELECT codigo_int, status from DB_prueba.dbo.producto where len (codigo_int)=8;";
$result = mssql_query($sql) or die("MS-Query Error in select-query");
while ($row = mssql_fetch_array($result))
{
$matriz8[$cont]=$row;
$cont=$cont+1;
}
mssql_close ($conectID);
  #7 (permalink)  
Antiguo 07/10/2008, 09:20
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 17 años, 11 meses
Puntos: 2135
Respuesta: Lentitud extrema con php

Creo un problema potenial es al usar: file(archivo) ya que tiene que leer TODO el archivo y pasarlo a una variable por lo que si tu archivo es grande tiene potencial a generar errores, lo mejor en este caso es usar fopen/fread/fclose para ir leyendo el archivo por partes y asi no ahogar el procesador.

Saludos.
  #8 (permalink)  
Antiguo 07/10/2008, 09:46
 
Fecha de Ingreso: agosto-2008
Ubicación: Argentina
Mensajes: 19
Antigüedad: 15 años, 8 meses
Puntos: 0
Respuesta: Lentitud extrema con php

$ar=fopen("datos.txt","r") or
die("No se pudo abrir el archivo");
while (!feof($ar))
{
$linea=fgets($ar);
$lineasalto=nl2br($linea);
echo $lineasalto;
}
fclose($ar);


si haces algo asi levanta linea por linea y usa las mismas comparaciones que usas cambiarias el for y lo que esat arriba por este while con el fopen, me explico



un abrazo espero te sirva

cualquier cosa ya sabes !
  #9 (permalink)  
Antiguo 07/10/2008, 10:35
 
Fecha de Ingreso: agosto-2008
Ubicación: Caracas
Mensajes: 51
Antigüedad: 15 años, 8 meses
Puntos: 0
Respuesta: Lentitud extrema con php

Gracias Marcos, GatorV:

Realice el cambio del for por el while para asi poder utilizar el fopen() en vez del file() pero la sorpresa que me encontre fue que al contrario de lo que esperabamos el tiempo de ejecucion con este metodo fue mas largo que utilizando el metodo anterior
con el mismo archivo txt con 654 registros (filas) el tiempo de ejecucion fue el siguiente:
utilizando el file() fue de 170.22604894638 segundos
y utilizando el fopen() fue de 179.29245591164 segundos.

en estos casos la diferencia no es mucha pero al momento de utilizar un archivo completo la diferencia si seria notable.

No se si la utilizacion de if anidados puede estar afectando el tiempo y ue me recomendarian en este caso? usar switch o que?
  #10 (permalink)  
Antiguo 07/10/2008, 10:46
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 17 años, 11 meses
Puntos: 2135
Respuesta: Lentitud extrema con php

A lo mejor con un archivo de prueba fue menor pero en cuanto a uso de memoria es más optimo ya que vas leyendo y borrando.

Lo que te recomendaria es que checaras bien el algoritmo que usas para comparar ya que veo muchos ifs, y ciclos dentro, eso puede causar el que se llegue a tardar tanto.

Saludos.
  #11 (permalink)  
Antiguo 07/10/2008, 10:48
 
Fecha de Ingreso: agosto-2008
Ubicación: Argentina
Mensajes: 19
Antigüedad: 15 años, 8 meses
Puntos: 0
Respuesta: Lentitud extrema con php

for ($m=0; $m < $cont; $m++) <- en este for el $cont en donde lo cargas

for ($i=0;$i<$cont2;$i++)-< en este for el $cont en donde lo cargas
  #12 (permalink)  
Antiguo 07/10/2008, 11:06
 
Fecha de Ingreso: abril-2006
Mensajes: 1.128
Antigüedad: 18 años
Puntos: 33
Respuesta: Lentitud extrema con php

josefrl:
Puede ser que donde estas guardando los resultados de la consulta a la BD este dandote problema por ser demasiados.
Prueba guardando los resultados en un archivo de texto de forma ordenada uno tras otro y para consultar simplemente utiliza file(archivo.txt) y lo buscas
a ver si eso acelera el sistema o lo retrasa aun mas.
Si esto no funciona, pues pareciera que habria que reinstalar los servidores
y cambiar el equipo porque podria estar defectuoso.
Personalmente NO creo que el script este causando eso.
Saludos
Y espero te ayude
Franco
  #13 (permalink)  
Antiguo 07/10/2008, 11:51
 
Fecha de Ingreso: agosto-2008
Ubicación: Caracas
Mensajes: 51
Antigüedad: 15 años, 8 meses
Puntos: 0
Respuesta: Lentitud extrema con php

Hola Marcos, las variables $cont y $cont2 las tomo de la carga de los datos a memoria me van dando el numero de registros de cada consulta.
Franco, las consultas que voy almacenando en memoria son un poco "grandes" en cantidad pero sin embargo en esas consultas no me traigo todos los campos de las base de dato sino solo los campos (a lo sumo 2) que voy a necesitar para hacer las validaciones. Son aproximadamente 50.000 registros que almaceno en memoria, voy a probar guardandolos en archivos txt pero te parece que 50.000 registros son demasiados para la memoria?
Gator, una alternativa que pueda utilizar te parece la de cambiar los IF por switch? es mas rapido el desenvolvimiento con los switches que con los if?
  #14 (permalink)  
Antiguo 07/10/2008, 15:55
 
Fecha de Ingreso: abril-2006
Mensajes: 1.128
Antigüedad: 18 años
Puntos: 33
Respuesta: Lentitud extrema con php

josefrl:
50000 registros te pueden utilizar un maximo de 75bytes por registro
osea 3750000bytes osea 3.750kb osea 3.75MB.
Si esa cantidad se almacena en la memoria temporal, considero que
seria muy pero muy lenta y eso nada tiene que ver con php.
Creo que php hace lo que el sistema y sus capacidades le permiten.
Si lo almacenas en un archivo de texto, la busqueda NO utiliza mucha memoria
y podria ser muchisimo mas rapido. Aunque parezca contradictorio.
En todo caso seria mucho mas practico consultar la BD remota; sin embargo una BD remota requiere de conexion remota e intercambio de comunicacion antes de permitir la conexion y por ende tiende a ser mas lenta.
Saludos
Franco
  #15 (permalink)  
Antiguo 07/10/2008, 16:17
 
Fecha de Ingreso: agosto-2008
Ubicación: Caracas
Mensajes: 51
Antigüedad: 15 años, 8 meses
Puntos: 0
Respuesta: Lentitud extrema con php

Gracias por la recomendacion Franco, en realidad no son 50.000 registros son 500.000 probe almacenandolos en archivos txt y entre todos sumaban aprox 4MB. Ahora voy a trabajarlo con esos archivos y hacer las validaciones contra ellos. En realidad soy nuevo programando e ignoraba las consecuencias que me podia acarrear el almacenar esos datos en memoria, simplemente pense que de esa manera las validaciones se iban a hacer mas rapido pero no pense en lo que podia ocasionar el tener la memoria tan sobreutilizada. en lo que termine de hacer los cambios les informo pero de antemano muchas gracias por sus ayudas
  #16 (permalink)  
Antiguo 08/10/2008, 10:42
 
Fecha de Ingreso: abril-2006
Mensajes: 1.128
Antigüedad: 18 años
Puntos: 33
Respuesta: Lentitud extrema con php

josefrl:
Penetrando un poco mas sobre tu caso, ya que es indudablemente interesante.
Esta la posibilidad que almacenes los datos temporales utilizando la funcion:
ob_start() y sus derivadas.
Estas funcionan mientras el script esta corriendo.
De tratar de utilizarlas se requiere de modificar el php.ini donde dice:
; - output_buffering = 4096 [Performance]
; Set a 4KB output buffer. Enabling output buffering typically results in less
; writes, and sometimes less packets sent on the wire, which can often lead to
; better performance. The gain this directive actually yields greatly depends
; on which Web server you're working with, and what kind of scripts you're using.

Ya que esta por defecto para 4.kp y para 50MB seria 50000000.
Asimismo, toda la informacion de como exactamente funciona ob_start() y sus derivadas pues el manual tiene informacion de sobra:
ob_start
(PHP 4, PHP 5)
ob_start — Habilitar el uso de búferes de salida
Descripción
bool ob_start ([ callback $llamada_de_retorno_salida [, int $tamanyo_segmento [, bool $borrar ]]] )
Esta función habilitará el uso de búferes de salida. Mientras los búferes de salida están activos no se envía salida desde el script (más que las cabeceras), en su lugar la salida es almacenada en un búfer interno.
Los contenidos de este búfer interno pueden ser copiados a una variable de cadena usando ob_get_contents(). Para producir la salida de lo que está almacenado en el búfer interno, use ob_end_flush(). Alternativamente, ob_end_clean() descartará silenciosamente los contenidos del búfer.
âra mi es claro que activando los buffers se puede almacenar grandes cantidades de datos en un buffer.

Te advierto que jamas he probado esto, si me intriga, si podra funcionar.
No se exactamente si es algun tipo de almacenamiento permanente, creo que si lo es ya que desde otro script creo que se puede llamar a la funcion y manejar los datos.
Francamente, no se exactamente, pero talvez, los amigos foristas pueden aportar algo a este tema interesante.
Saludos
Y buena Suerte.
Franco
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 17:09.