Sehr langsames SchleifenverhaltenIch habe eine Frage bezüglich der in Schleifen verbrachten Zeit.
Ich analysiere größere Mengen an Produktionsdaten, normalerweise 1 Million Zeilen.
Für jede Zeile erfasst die Produktion den Status (Spalte Statusnummer).
Wenn der Status „1“ ist, dann möchte ich die Werte für Ist („ist“) und Sollwert („soll“) berechnen.
Ich muss also 1 Million Zeilen berechnen. Ich mache das in meinem Code oft für verschiedene Werte.
Manchmal sind die Schleifen schnell (60 Sekunden), manchmal sind sie sehr (!) langsam (länger als ein Tag! Der Prozessor arbeitet immer noch unter Volllast!).
Alle Spalten sind auf numerisch und kontinuierlich eingestellt, aber ich kann nicht herausfinden, warum einige Schleifen sehr langsam sind.
Ich habe sogar überprüft, ob die Zelle fehlende Werte enthält (siehe Beispielcode); Trotzdem bleibt der Code langsam.
Irgendeine Idee, was ich falsch mache?
Marder
Beispielcode, der langsam ist:
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;
));
));
));
Betreff: Sehr langsames Schleifenverhalten@vince_faller Cool! Ich sehe nur etwa 10x schneller (was immer noch ziemlich erstaunlich ist). Ich vermute, dass diese Beschleunigung nichts mit der Aktualisierung der Anfangs-/Enddaten zu tun hat, aber ich denke auch, dass die Matrixzuweisungen intern so etwas wie die Aktualisierung der Anfangs-/Enddaten bewirken werden.
@EvanMcCorkle
Betreff: Sehr langsames SchleifenverhaltenDanke, wahrscheinlich (siehe Kommentar oben, das Problem ist inzwischen verschwunden) war das der Grund, da viele Berichte offen waren. Aber ich kann es momentan nicht reproduzieren. Ich werde Ihre Lösung in meinen Code einführen und prüfen, ob es sich um eine dauerhafte Lösung handelt.
MarderBetreff: Sehr langsames SchleifenverhaltenAktualisieren : Ich habe die Methode „Zeilen abrufen, wo“ zum Suchen der Zeilen hinzugefügt.Natürlich unterliegt dies der Einschränkung, dass numerische Daten erforderlich sind, aber manchmal kann ich das umgehen.
Ich bin ein großer Fan davon, alles mit Matrizen zu machen.
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);
Als ich diesen Vergleich durchführte, bekam ich
t_loop = 11259288;
t_mat = 206942;
Aktualisiert
t_loop = 11950585;
t_mat = 205366;
t_get_where = 6742823;
Betreff: Sehr langsames SchleifenverhaltenDas könnte die Sache beschleunigen – beschränken Sie Ihre Schleife auf nur die Zeilen, die Ihren Bedingungen entsprechen.
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] ;
);Betreff: Sehr langsames SchleifenverhaltenMöglicherweise haben Sie einen anderen Bericht geöffnet, der bei jeder Änderung, die Sie an der Tabelle vornehmen, aktualisiert wird. Sie könnten dies vor und nach Ihrer Schleife tun:
dt << Begin Data Update;
// the loop
dt << End Data Update;
Betreff: Sehr langsames Schleifenverhalten|Hallo Ron, danke. Die verschachtelten Schleifen sollen es schneller machen,
weil die erste Bedingung in vielen Zeilen fehlschlägt, sodass die Schleife dies kann
(und tut) beginnen Sie von oben mit der nächsten Zeile. also von der Funktionalität her
funktioniert alles. Ich habe jedoch noch einmal nachgesehen, wo es langsam wird. Im
Debugger, der Zugriff auf die Datentabelle zum Zurückschreiben der Werte dauerte lange:
dt:Soll_drehzahl[i] = soll; dt:Ist_drehzahl[i] = ist;
dt:Maschinenleistung[i] = 100*ist/soll;|
Also habe ich sie auskommentiert (//) ==> Ergebnis: sehr schnell
Ich habe die Kommentarzeichen (//) gelöscht und ..... immer noch sehr schnell (!)
.......(Gleicher Code, gleiche Struktur,....)
Es funktioniert also jetzt, aber ich weiß immer noch nicht, was das Problem verursacht hat. Vielleicht
Etwas in meinem System ist beschädigt.
Danke für die Vorschläge.
Betreff: Sehr langsames SchleifenverhaltenHallo @MWalther
Ich würde versuchen, dies zu tun, wie Jeff vorgeschlagen hat, indem ich Spaltenformeln verwende. Vergessen Sie nicht, dass Sie die Formeln jederzeit entfernen oder ihre Auswertungen einfach unterdrücken können, wenn Sie nicht möchten, dass sie ständig neu ausgewertet werden.
Wenn Sie darauf bestehen, die for-Schleifenmethode zu verwenden, würde ich zunächst prüfen, ob die letzten paar Semikolons erforderlich sind.
Darüber hinaus würde ich versuchen, die verschachtelte if-Anweisung in eine längere Liste von Bedingungen zu vereinfachen.
Verwenden Sie schließlich den De-Bugger für ein Sub-Sample und sehen Sie, was in der Schleife mehr Zeit in Anspruch nimmt. Ich habe das Gefühl, dass etwas Unbeabsichtigtes die meiste Zeit in Anspruch nimmt.
Lassen Sie uns wissen, wenn sich etwas verbessert.
Betreff: Sehr langsames SchleifenverhaltenLieber Jeff, danke für die Antwort. Formeln an dieser Stelle des Skripts
nicht helfen. (Dies ist mein Sortier- und Datenbereinigungsbereich, wo ich möchte
Formeln vermeiden)
Ich habe das gleiche Problem an verschiedenen Stellen. Und einige Formeln
waren ebenfalls betroffen.
Es scheint, dass der Prozess fast vollständig einfriert (ich habe 1 gezählt).
Zeile/Sekunde!) obwohl die CPU mit der Last weitermacht!
Das Ergebnis ist jedoch korrekt, sobald es fertig ist.
Euer Marten
Betreff: Sehr langsames SchleifenverhaltenHaben Sie versucht, diese Spalten in der Datentabelle mithilfe von zu erstellen? Formeleditor statt einer Schleife mit JSL? Das könnte effizienter sein.