• Publicidad

script consume mucha CPU pero poca memoria

¿Apenas comienzas con Perl? En este foro podrás encontrar y hacer preguntas básicas de Perl con respuestas aptas a tu nivel.

script consume mucha CPU pero poca memoria

Notapor preiddy » 2009-08-05 12:50 @577

Hola, después de unas largas y muy largas vacaciones he vuelto a Perl, de donde no me he debí de ir, jajaja.

Un compañero de trabajo y yo estamos tratando de optimizar un script ya que consume mucha CPU pero no memoria. Disponemos de un equipo con una Intel Core Duo y 2Gb de RAM, y de RAM no consume más de 32mb. Necesitamos CPU para otros procesos, sobre todo para la BD que está en MySQL.

El script son dos arrays que se comparan usando el paquete trigrams.
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
$array  = $sth->fetchall_arrayref;
$array2 = $sth2->fetchall_arrayref;

for my $lineas ( @{$array} ) {
    for my $lineas2 ( @{$array2} ) {
        my $smlty = String::Trigram::compare( $lineas->[0], $lineas2->[0]);
        if ( $smlty >= 0.9 ) {
            print "$smlty\t$lineas->[0]\t=\t$lineas2->[0]\n";
        }
    }
}
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4

Dependiendo de su similaridad iremos creando elsif() para cada uno y las acciones que han de tomar.

¿Es posible optimizarlo?

Las listas no bajan de 1 millón de registros en la BD y son nombres de calles.

¡¡¡Muchas gracias!!!
Última edición por explorer el 2009-08-06 09:38 @443, editado 2 veces en total
Razón: Ortografía, sintaxis, anglicismos, bloques de código
preiddy
Perlero nuevo
Perlero nuevo
 
Mensajes: 70
Registrado: 2006-03-29 05:43 @280
Ubicación: Madrid, España

Publicidad

Re: script consume mucha CPU pero poca memoria

Notapor explorer » 2009-08-06 09:51 @452

Si lo entiendo bien, queréis que la aplicación use menos CPU porque la necesitáis para otros procesos.

Bueno, es otra forma de decir que queréis que vaya algo más lento :)

Si estáis en Linux/UNIX es muy sencillo, porque solo tenéis que lanzar la aplicación con un cierto nivel de nice (una prioridad más baja).

Por ejemplo,
Sintáxis: [ Descargar ] [ Ocultar ]
Using bash Syntax Highlighting
nice 5 programa_perl.pl
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4


De esta manera, el proceso solo usará el tiempo de CPU que quede libre después de dárselo a los principales.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14486
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: script consume mucha CPU pero poca memoria

Notapor preiddy » 2009-08-10 12:51 @577

Ok, muchas gracias.

¿Y si quiero que use más memoria, qué tendría qué hacer / ejecutar?
preiddy
Perlero nuevo
Perlero nuevo
 
Mensajes: 70
Registrado: 2006-03-29 05:43 @280
Ubicación: Madrid, España

Re: script consume mucha CPU pero poca memoria

Notapor explorer » 2009-08-10 16:38 @735

En un problema tan sencillo como este (comparar nombres de dos bases de datos), no se me ocurren muchas formas de aumentar el procesamiento a costa de aumentar la memoria.

En otras situaciones usaría el módulo Memoize para recordar comparaciones a costa de usar más memoria, pero es que en este caso, no se da esa circunstancia: siempre hay que comparar todos los valores de una con la del otro.

Habría optimizaciones interesantes, como por ejemplo, si dos calles coinciden, suponemos que es la misma, entonces, las sacamos de los arreglos. De esta manera, los arreglos se van haciendo cada vez más pequeños. Y aumenta la velocidad.

Otra opción que se me ocurre: ordenar antes (con sort()) los arreglos que guardan el nombre de las calles. Se supone entonces que las calles con igual letra estarán a un mismo nivel de profundidad. Y si le añadimos la opción de sacarlos de los arreglos si coinciden, entonces irá más rápido aun.

Como regla general, si alguien pregunta cómo aumentar el consumo de memoria para intentar aumentar el rendimiento del programa, la solución es decirle que cambie el modelo de datos que está usando, que es lo que te he comentado en los párrafos anteriores.

Falta más información sobre cómo son los datos o el problema, para dar más pistas. Si solo es el código mostrado, otra posibilidad que se me ocurre es intentar optimizar la función String::Trigram::compare(). O usar otra menos costosa.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14486
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: script consume mucha CPU pero poca memoria

Notapor preiddy » 2009-09-02 14:03 @627

Después de una pequeñas vacaciones de verano, de regreso al trabajo, jajaja.

Efectivamente es necesario comparar una contra la otra, ya que la otra es una lista que ya hemos trabajado y digamos que tenemos bien localizadas, la cosa es a las nuevas contrastarlas con las que tenemos. Por eso, la opción de sacar del arreglo si coinciden no nos resulta útil.

Cuando hacemos las consultas, ambas ya vienen ordenadas, sí que se gana tiempo, el primer test que hicimos tardó poco más del doble de tiempo sin "order by".

Sugieres usar otra menos costosa ¿como cuál?

¡¡¡De nuevo gracias por dar respuestas a mis dudas!!!
preiddy
Perlero nuevo
Perlero nuevo
 
Mensajes: 70
Registrado: 2006-03-29 05:43 @280
Ubicación: Madrid, España

Re: script consume mucha CPU pero poca memoria

Notapor explorer » 2009-09-02 16:08 @714

Cuando yo me refiero a sacar del arreglo los coincidentes, quiero decir que voy desalojando los arreglos de búsqueda, pero, desde luego, voy almacenando los encontrados en un nuevo arreglo o estructura de datos.

En el ejemplo que pones, estás imprimiendo esos resultados. Pues a eso me refiero: si dos elementos a comparar les puedo considerar iguales, les imprimo y/o guardo y los elimino de los arreglos de búsqueda (porque ya les he localizado). O al menos la elimino del arreglo de las nuevas calles. El objetivo es ir haciendo el arreglo de las nuevas calles cada vez más pequeño y evitar hacer comparaciones con calles que ya he localizado.

En cuanto a las alternativas, hay en CPAN unos cuantos módulos para hacer comparaciones entre cadenas de texto. Algunos de ellos están al final de la documentación del propio String::Trigram. Además, agrego String::Diff, String::Alignment, String::Compare, String::CyclicRotation, String::Examine, String::KeyboardDistance, String::LCSS y el último en aparecer, hace unos días, String::Similarity::Group.

Te cuento que yo mismo tuve que enfrentarme a un problema parecido, cuando había que "casar" nombres de personas de 3 bases de datos distintas, la más pequeña de 200.000 y la más grande de casi 3 millones. Usando diversas técnicas, con los módulos indicados (incluyendo el Soundex, que dio muy buen juego), se redujeron los no coincidentes a 4000, que no hubo manera de casar más que yendo uno por uno. Pero bueno, en unas horas los hicimos coincidir a todos.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14486
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: script consume mucha CPU pero poca memoria

Notapor preiddy » 2009-09-04 02:28 @144

jajaja, eso es exactamente lo que necesito y claro está que tengo más de un año haciéndome el loco / tonto para no resolver lo de los nombre de personas, que en mi caso es de más de 2 millones. La diferencia entre las calles y las personas, es que de ésta última solo tenemos unos pocos bien identificados.
Última edición por explorer el 2009-09-04 03:10 @173, editado 1 vez en total
Razón: Estilo: "solo tenemos"
preiddy
Perlero nuevo
Perlero nuevo
 
Mensajes: 70
Registrado: 2006-03-29 05:43 @280
Ubicación: Madrid, España

Re: script consume mucha CPU pero poca memoria

Notapor preiddy » 2009-09-29 18:00 @791

Sigo dándole vueltas y no mejoro nada, la opción de si dos nombres de calles coinciden sacarla del array me gusta, pero no consigo hacerlo.

Añado shift(@{$array}); después de cada if(), pero no funciona.

¿Qué estoy haciendo mal?

Estoy un poco desesperado, jajajajaa.
preiddy
Perlero nuevo
Perlero nuevo
 
Mensajes: 70
Registrado: 2006-03-29 05:43 @280
Ubicación: Madrid, España

Re: script consume mucha CPU pero poca memoria

Notapor explorer » 2009-09-29 19:00 @833

Con shift() estás sacando el primer elemento del @$array. ¿Seguro que es el primer elemento el que quieres sacar?

En circunstancias parecidas, tenía que quitar elementos que estaban en mitad del array. Para eso, se utiliza la función splice().

En cuanto al código, sería interesante ver si has hecho algún cambio importante con respecto al que mostraste en el primer mensaje, porque al verle, me he dado cuenta de que, al encontrar dos calles coincidentes, se podría hacer que no siguiera en el bucle más interior, saliendo con un last, por ejemplo.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14486
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: script consume mucha CPU pero poca memoria

Notapor preiddy » 2009-09-30 01:24 @100

No, la verdad es que hice tantas pruebas que me volví a la primera versión ya que, aunque es lenta funciona bastante bien.

Unos ejemplos de calles:
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
Av. Ciudad Universitaria, Caracas, 1050, Venezuela.
Av. Ciudad Universitaria, Chaguaramos Caracas, 1080, Venezuela.
Av. Ciudad Universitaria, Caracas DF, Los Chaguaramos 1080, Vzla.
Av. Valle de Sartenejas, Baruta, 2890, Vzla.
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4


Tengo una tabla en MySQL con el nombre bien identificado y por lo general más desarrollado. Por ejemplo:

Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
Av. Ciudad Universitaria, Los Chaguaramos, CP.1050, Caracas (DC), Venezuela.
Av. Valle de Sartenejas, Municipio Baruta, CP.2890, Venezuela.
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4


El script:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
my $sth =
  $dbh->prepare(
        "select calle FROM dir where completo = ''  GROUP BY direc ORDER BY direc"
  );
$sth->execute();

my $sth2 =
  $dbh->prepare(
        "select UCASE(calle), compl FROM c1 GROUP BY calle ORDER BY calle");

$sth2->execute();
my $array  = $sth->fetchall_arrayref;
my $array2 = $sth2->fetchall_arrayref;

for my $lineas ( @{$array} ) {    ### Normalizando [|||        ] % Completado \n
        for my $lineas2 ( @{$array2} ) {

                my $smlty = String::Trigram::compare( $lineas->[0], $lineas2->[0], minSim => 0.5, ngram => 7, );
                my $tanto = sprintf( "%.2f", ( $smlty * 100 ) );
                if ( $smlty >= 0.9 ) {
                        print "\n$lineas->[0] \t => \t $lineas2->[0] \t $lineas2->[1]\t $tanto\n";
                        shift (@{$array});
                }
                elsif ( $smlty >= 0.8 ) {
                        print "\n$lineas->[0] \t => \t $lineas2->[0] $lineas2->[1]\t $tanto\n";
                        shift (@{$array});
                }
                elsif ( $smlty >= 0.7 ) {
                        print "\n$lineas->[0] \t => \t $lineas2->[0] $lineas2->[1]\t $tanto\n";
                        shift (@{$array});
                }
                elsif ( $smlty >= 0.6 ) {
                        print "\n$lineas->[0] \t => \t $lineas2->[0] $lineas2->[1]\t $tanto\n";
                        shift (@{$array});
                }
                elsif ( $smlty >= 0.5 ) {
                        print "\n$lineas->[0] \t => \t $lineas2->[0] $lineas2->[1]\t $tanto\n";
                        shift (@{$array});
                }
        }
}
$sth->finish();
$sth2->finish();
$dbh->disconnect()
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4


Claro, ahora me doy cuenta que, ciertamente, el valor no tiene por qué ser el primero. Voy a peor, jajajaja.
preiddy
Perlero nuevo
Perlero nuevo
 
Mensajes: 70
Registrado: 2006-03-29 05:43 @280
Ubicación: Madrid, España

Siguiente

Volver a Básico

¿Quién está conectado?

Usuarios navegando por este Foro: Google [Bot] y 0 invitados

cron