リスト ボックスのコンテンツ更新を最適化します。JMPコミュニティの皆様、こんにちは。
最近、内部 JSL スクリプトのパフォーマンスを改善する方法を検討していたところ、次のようなパフォーマンスの問題が見つかり、対処したいと思っています。
次のスクリプトを見てみましょう (macOS で実行されている JMP 17.2 PRO):
Names Default To Here( 1 );
dt = Open( "$SAMPLE_DATA/Big Class.jmp" );
values = Column( dt, 1 )[dt << get rows where( Excluded( Row State() ) != 1 )];
new window("test",
lb = list box( values, nlines(10), width(100), ),
b = button box("reset", reset_lb),
);
reset_lb = expr(
lb << remove all();
lb << append(values);
Nnames = N Items(values);
for(i = 1, i <= Nnames, i++,
lb << set selected(i);
);
);いくつかのスクリプトでは、動的に更新されるリスト ボックスを使用しています。リスト ボックスの内容を変更するために、 << remove()関数と<< append()関数を使用しています。これらの関数は問題なく動作しますが、このメソッドは行数に応じてあまり拡張できないのではないかと思います。驚くほど実行速度が遅い別の部分は、<< set selected()を使用した for ループです。どうやら、これがリスト ボックス内のすべての項目を選択するために見つけた唯一のメソッドのようですが、行数に応じてひどく拡張されます。
私の質問は、パフォーマンスを低下させずにリスト ボックスのコンテンツを更新するための最もよく知られている方法があるかどうかです。次のような代替手段を探しています。
- リスト ボックスの内容を設定する最適な方法。
- リスト ボックスのすべての項目を選択するための高速な方法。
フィードバックや提案があれば、ぜひお聞かせください。
自動化とスクリプトデータの探索と視覚化マックOSRe: リスト ボックス コンテンツの更新を最適化します。リストボックスにはいくつの項目を入れる予定ですか?1つなら、<
編集:
Re: リスト ボックス コンテンツの更新を最適化します。こんにちは、ジャーモさん
返信ありがとうございます。<
項目数に関しては、約 30,000 個ですが、奇妙なことに、スクリプトをロードすると、コンテンツを更新するよりも、最初から lb を設定する方がはるかに時間がかかります。リスト ボックスを削除してから再度作成する方法を考えていましたが、スクリプトでこれらすべての変更を行うのは非常に難しいかもしれません。
Re: リスト ボックス コンテンツの更新を最適化します。どちらの方法も私の意見ではかなり速いと感じます
Names Default To Here(1);
rowcount = 100000;
dt = New Table("Demo",
Add Rows(rowcount),
New Column("Values", Character, Nominal, << Set Each Value(
Hex(Row()) || Hex(Row()) || Hex(Row())
))
);
values = Column(dt, 1)[dt << get rows where(Excluded(Row State()) != 1)];
Close(dt, no save);
nw = New Window("test",
H List Box(
H List Box(
lb1 = List Box(values, nlines(10), width(100)),
Button Box("reset", reset_lb1),
)
),
H List Box(
H List Box(
lb2_collector = V List Box(
lb2 = List Box(values, nlines(10), width(100)),
),
Button Box("reset2", reset_lb2),
)
)
);
reset_lb1 = Expr(
start1 = HP Time();
lb1 << Set Items(values);
end1 = HP Time();
start2 = end1;
Nnames = N Items(values);
For(i = 1, i <= Nnames, i++,
lb1 << set selected(i);
);
end2 = HP Time();
Show((end1 - start1)/1e6, (end2-start2)/1e6, (end2-start1)/1e6);
);
reset_lb2 = Expr(
start3 = HP Time();
vlb = V List Box(lb2 = List Box(values, nlines(10), width(100)));
For Each({val, idx}, values,
lb2 << set selected(idx);
);
While(!IsEmpty(lb2_collector << child),
(lb2_collector << child) << delete box;
);
lb2_collector << Append(vlb);
end3 = HP Time();
Show((end3 - start3)/1e6);
);
Write();Re: リスト ボックス コンテンツの更新を最適化します。注意すべき点は、<< Set Selected はデフォルトでリスト ボックスに関連付けられたスクリプト (存在する場合) を実行することです。関連付けられたスクリプトがあるが、各セットでトリガーしたくない場合は、<< Set Selected(idx, 1, Run Script(0)) を使用します (必要に応じて、最後のセットでトリガーできます)。
Names Default To Here(1);
rowcount = 100000;
dt = New Table("Demo",
Add Rows(rowcount),
New Column("Values", Character, Nominal, << Set Each Value(
Hex(Row()) || Hex(Row()) || Hex(Row())
))
);
values = Column(dt, 1)[dt << get rows where(Excluded(Row State()) != 1)];
Close(dt, no save);
nw = New Window("test",
H List Box(
lb2_collector = V List Box(
lb2 = List Box(values, nlines(10), width(100), Show(1)),
),
Button Box("reset2", reset_lb2),
)
);
reset_lb2 = Expr(
start3 = HP Time();
vlb = V List Box(lb2 = List Box(values, nlines(10), width(100), Show(1)));
For(i = 1, i < N Items(values), i++,
lb2 << set selected(i, 1, Run Script(0));
);
lb2 << set selected(N Items(values), 1, Run Script(1));
While(!IsEmpty(lb2_collector << child),
(lb2_collector << child) << delete box;
);
lb2_collector << Append(vlb);
end3 = HP Time();
Show((end3 - start3)/1e6);
);
Write();
Re: リスト ボックス コンテンツの更新を最適化します。デモンストレーションをありがとうございます。私のマシンでは、2 番目の方法の方が約 5 倍高速で、最初の方法のほとんどの時間は、選択したループの設定に費やされていることがわかります。