ループ動作が非常に遅いループにかかる時間について質問があります。
私は、通常 100 万行の大量の実稼働データを分析しています。
各行について、本番環境はステータス (Statusnummer 列) を取得します。
ステータスが「1」の場合、実際の値(「ist」)と設定値(「soll」)の値を計算したいと思います。
したがって、1mio行を計算する必要があります。 コード内でさまざまな値に対してこれを何度も実行しています。
ループが速い場合 (60 秒) もあれば、非常に (!) 遅い (1 日以上!) 場合もあります。 プロセッサーはまだ全負荷で動作しています!)。
すべての列は数値および連続に設定されていますが、一部のループが非常に遅い理由がわかりません。
セルに欠損値が含まれているかどうかもチェックしました(サンプルコードを参照)。それでもコードは遅いままです。
何か考えはありますか、私が何を間違っているのでしょうか?
マーテン
遅いコードのサンプル:
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: ループ動作が非常に遅い@vince_fallerいいね! 約 10 倍の高速化しか確認できません (それでもかなり驚くべきことです。) この高速化は開始/終了データの更新とは関係がないと思われますが、行列の割り当てが内部で開始/終了データの更新のようなことを行うのではないかとも考えています。
@EvanMcorkle
Re: ループ動作が非常に遅いありがとう、おそらく (上記のコメントを参照、問題はその間に消えました) 多くのレポートが公開されていたため、これが理由でした。 しかし、今のところ再現できません。 あなたの解決策を私のコードに導入し、それが永続的な修正であるかどうかを確認します。
マーテンRe: ループ動作が非常に遅いアップデート: 行を検索する get rows where メソッドを追加しました。明らかに、これには数値データが必要であるという制限がありますが、場合によってはそれを回避できることがあります。
私は行列を使ってあらゆることを行うのが大好きです。
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);
この比較を実行すると、次のようになりました
t_loop = 11259288;
t_mat = 206942;
更新しました
t_loop = 11950585;
t_mat = 205366;
t_get_where = 6742823;
Re: ループ動作が非常に遅いこれにより、処理が高速化される可能性があります。条件を満たす行のみにループを制限します。
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: ループ動作が非常に遅いおそらく、別のレポートが開いていて、テーブルに変更を加えるたびに更新されている可能性があります。 ループの前後でこれを行うことができます。
dt << Begin Data Update;
// the loop
dt << End Data Update;
Re: ループ動作が非常に遅い|こんにちはロン、ありがとう。 ネストされたループは高速化を目的としています。
最初の条件が多くの行で失敗するため、ループは
次の行を使用して上から開始します (実際に実行します)。なので機能面から
すべてが機能します。 しかし、どこが遅いのか再確認してみました。 の中に
デバッガでは、値を書き戻すためのデータ テーブルへのアクセスに時間がかかりました。
dt:Soll_drehzahl[i] = ソル; dt:Ist_drehzahl[i] = ist;
dt:Maschinenleistung[i] = 100*ist/soll;|
そこで、それらをコメントアウトしました (//) ==> 結果: 非常に高速です
コメントマーク (//) を消してみましたが、それでも非常に高速です (!)
......(同じコード、同じ構造、....)
現在は機能していますが、問題の原因はまだわかりません。 多分
システム内の何かが壊れています。
ご提案ありがとうございます。
Re: ループ動作が非常に遅いこんにちは@MWalther
Jeff が提案したように、列数式を使用してこれを実行してみます。常に再評価されたくない場合は、いつでも数式を削除したり、その評価を抑制したりできることを忘れないでください。
for ループメソッドを使用することを主張する場合は、最初に最後のいくつかのセミコロンが必要かどうかを確認します。
さらに、ネストされた if ステートメントを 1 つの長い条件リストに単純化してみます。
最後に、サブサンプルでデバッガーを使用して、ループ内の何がより時間がかかるかを確認します。 意図しない処理が行われていて、ほとんどの時間がかかっているような気がします。
何か改善された場合はお知らせください。
Re: ループ動作が非常に遅い親愛なるジェフさん、ご回答ありがとうございます。 スクリプトのその場所の数式
役に立ちません。 (これは私の並べ替えとデータ クリーニングのセクションです。
公式を避けるため)
別の場所で同じ問題に直面しています。 そしていくつかの公式
も影響を受けました。
どうやら、プロセスがほぼ完全にフリーズしているようです(私は1つ数えました)
行/秒!) ただし、CPU は負荷を継続します。
ただし、完了すると結果は正しいです。
あなたのマーテン
Re: ループ動作が非常に遅いを使用してデータテーブルにこれらの列を構築してみましたか?数式エディタJSLでループする代わりに? そのほうが効率的かもしれません。