Comportamiento de bucle muy lentoTengo una pregunta sobre el tiempo invertido en bucles.
Estoy analizando grandes cantidades de datos de producción, normalmente 1 millón de filas.
Para cada fila, la producción captura el estado (columna Statusnummer).
Si el estado es "1", entonces me gustaría calcular los valores reales ("ist") y establecer el valor ("soll").
Entonces necesito calcular 1 millón de filas. Hago esto muchas veces en mi código, para diferentes valores.
A veces, los bucles son rápidos (60 segundos), a veces son muy (!) lentos (¡más de un día! ¡El procesador sigue funcionando a plena carga!).
Todas las columnas están configuradas como numéricas y continuas, pero no puedo entender por qué algunos bucles son muy lentos.
Incluso verifiqué si la celda contiene valores faltantes (ver código de muestra); Aún así, el código sigue siendo lento.
¿Alguna idea de qué estoy haciendo mal?
Marta
Muestra del código, que es lento:
for(i=1,i<=NRows(dt),i++,(
if(dt:Statusnummer[i] == 1,(
if(!isMissing(dt:Drehzahl[i]) & !isMissing(dt:geschw[i]) ,(
ist = dt:Drehzahl[i];
soll = dt:SollDrehzahl[i];
dt:Soll_drehzahl[i] = soll;
dt:Ist_drehzahl[i] = ist;
dt:Maschinenleistung[i] = 100*ist/soll;
));
));
));
Re: Comportamiento de bucle muy lento@vince_faller ¡Fresco! Solo veo alrededor de 10 veces más rápido (lo cual sigue siendo bastante sorprendente). Sospecho que esta aceleración no está relacionada con la actualización de datos de inicio/final, pero también creo que las asignaciones de matriz harán algo como la actualización de datos de inicio/final internamente.
@EvanMcCorkle
Re: Comportamiento de bucle muy lentoGracias, probablemente (ver comentario arriba, el problema desapareció mientras tanto) esta fue la razón, ya que había muchos informes abiertos. Pero no puedo reproducirme ahora. Introduciré su solución en mi código y veré si es la solución permanente.
MartaRe: Comportamiento de bucle muy lentoActualizar : Agregué el método obtener filas donde para encontrar las filas.Obviamente, esto tiene la restricción de requerir datos numéricos, pero a veces puedo evitarlo.
Soy un gran admirador de hacer todo con matrices.
Names default to here(1);
dt = New Table("Test",
Add Rows(1000000),
New Column("Statusnummer", Set Each Value(Random Integer(0, 1))),
New Column("Drehzahl", Set Each Value(Choose(Random Integer(1, 2), ., Random Normal()))),
New Column("geschw", Set Each Value(Choose(Random Integer(1, 2), ., Random Normal()))),
New Column("SollDrehzahl", Set Each Value(Random Normal())),
New Column("Soll_drehzahl"),
New Column("Ist_drehzahl"),
New Column("Maschinenleistung"),
);
st = HPTime();
for(i=1,i<=NRows(dt),i++,
if(dt:Statusnummer[i] == 1,
if(!isMissing(dt:Drehzahl[i]) & !isMissing(dt:geschw[i]),
ist = dt:Drehzahl[i];
soll = dt:SollDrehzahl[i];
dt:Soll_drehzahl[i] = soll;
dt:Ist_drehzahl[i] = ist;
dt:Maschinenleistung[i] = 100*ist/soll;
);
);
);
t_loop = HPTime() - st;
st = HPTime();
m = dt[0, {"Statusnummer", "Drehzahl", "geschw"}]; // makes a matrix
//check the matrix
v = m[0, 1] // don't need to do a check if it's 0 or 1
&
!ismissing(m[0, 2]) // check if drehzahl is missing
&
!ismissing(m[0, 3]); // check if drehzahl is missing
rows = loc(v); // this is the rows you want to do stuff on now.
//now just set all at once
soll = dt[rows, "Soll_drehzahl"] = dt:SollDrehzahl[rows]; // assign the rows and variable simultaneously
ist = dt[rows, "Ist_drehzahl"] = dt:Drehzahl[rows]; // same thing
dt[rows, "Maschinenleistung"] = 100 * ist :*</img> (1/soll); // do an element wise matrix division
t_mat = HPTime() - st;
st = HPTime();
rows = dt << get rows where(dt:Statusnummer == 1 &
!Is Missing(dt:Drehzahl) &
!Is Missing( dt:geschw ));
//now just set all at once
soll = dt[rows, "Soll_drehzahl"] = dt:SollDrehzahl[rows]; // assign the rows and variable simultaneously
ist = dt[rows, "Ist_drehzahl"] = dt:Drehzahl[rows]; // same thing
dt[rows, "Maschinenleistung"] = 100 * ist :*</img> (1/soll); // do an element wise matrix division
t_get_where = HPTime() - st;
show(t_loop, t_mat, t_get_where);
Cuando realicé esta comparación, obtuve
t_loop = 11259288;
t_mat = 206942;
Actualizado
t_loop = 11950585;
t_mat = 205366;
t_get_where = 6742823;
Re: Comportamiento de bucle muy lentoEsto podría acelerar las cosas: restrinja su bucle solo a las filas que cumplan con sus condiciones.
found_rows = dt << get rows where(dt:Statusnummer == 1 &
!Is Missing(dt:Drehzahl) &
!Is Missing( dt:geschw ));
for (i = 1, i <= nrows(found_rows), i++,
k = found_rows[i];
dt:Soll_drehzahl[k] = dt:SollDrehzahl[k];
dt:Ist_drehzahl[k] = dt:Drehzahl[k];
dt:Maschinenleistung[k] = 100 * dt:Ist_drehzahl[k] / dt:Soll_drehzahl[k] ;
);Re: Comportamiento de bucle muy lentoQuizás tenga otro informe abierto y que se actualice con cada cambio que realice en la tabla. Puedes hacer esto antes y después de tu ciclo:
dt << Begin Data Update;
// the loop
dt << End Data Update;
Re: Comportamiento de bucle muy lento|Hola Ron, gracias. Los bucles anidados están destinados a hacerlo más rápido,
porque la primera condición falla en muchas líneas, de modo que el bucle puede
(y lo hace) comienza desde arriba usando la siguiente fila. entonces desde la funcionalidad
Todo funciona. Sin embargo, volví a comprobar dónde se vuelve lento. En el
depurador, el acceso a la tabla de datos para volver a escribir los valores tomó mucho tiempo:
dt:Soll_drehzahl[i] = soll; dt:Ist_drehzahl[i] = es;
dt:Maschinenleistung[i] = 100*ist/soll;|
Entonces los comenté (//) ==> resultado: muy rápido
Borré las marcas de comentarios (//) y..... todavía muy rápido (!)
.......(Mismo código, misma estructura,....)
Ahora funciona, pero todavía no sé qué causó el problema. Tal vez
algo en mi sistema está corrupto.
Gracias por las sugerencias.
Re: Comportamiento de bucle muy lentoHola @MWalther
Intentaría hacer esto como Jeff sugirió usar fórmulas de columna. No olvides que siempre puedes eliminar las fórmulas o simplemente suprimir sus evaluaciones una vez que no quieras que sean reevaluadas constantemente.
Si insistes en usar el método de bucle for, primero vería si los últimos puntos y coma son necesarios.
Además, intentaría simplificar la declaración if anidada en una lista más larga de condiciones.
finalmente, usar el depurador en una submuestra y ver qué en el bucle lleva más tiempo. Tengo la sensación de que se está haciendo algo no intencionado que lleva la mayor parte del tiempo.
háganos saber si algo mejora.
Re: Comportamiento de bucle muy lentoEstimado Jeff, gracias por la respuesta. Fórmulas en ese lugar del guión.
no ayudes. (Esta es mi sección de clasificación y limpieza de datos, donde quiero
para evitar fórmulas)
Tengo el mismo problema en diferentes lugares. Y algunas fórmulas
también fueron afectados.
Parece que el proceso se está congelando casi por completo (conté 1
fila/segundo!) aunque la CPU sigue con la carga!
El resultado, sin embargo, es correcto una vez terminado.
Tuya marta
Re: Comportamiento de bucle muy lento¿Has intentado construir esas columnas en la tabla de datos usando el Editor de fórmulas en lugar de hacer un bucle con JSL? Eso puede ser más eficiente.