Optimieren der Aktualisierung des Listenfeldinhalts.Hallo JMP-Community,
Ich habe kürzlich versucht, die Leistung meiner internen JSL-Skripte zu verbessern und bin auf die folgenden Leistungsprobleme gestoßen, die ich gerne beheben würde.
Nehmen wir das folgende Skript (JMP 17.2 PRO läuft unter macOS):
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);
);
);In einigen meiner Skripte verwende ich Listenfelder, die dynamisch aktualisiert werden. Um den Inhalt der Listenfelder zu ändern, verwende ich die Funktionen << remove() und << append(). Sie funktionieren einwandfrei, aber ich befürchte, dass diese Methode nicht sehr gut mit der Anzahl der Zeilen skaliert. Ein weiterer Teil, der überraschend langsam läuft, ist die For-Schleife mit << set selected(). Anscheinend ist dies die einzige Methode, die ich zum Auswählen aller Elemente in einem Listenfeld finden konnte, aber sie skaliert schrecklich mit der Anzahl der Zeilen.
Meine Frage ist, ob es eine bewährte Methode gibt, den Inhalt der Listenfelder zu aktualisieren, ohne dass die Leistung dadurch beeinträchtigt wird. Ich suche nach möglichen Alternativen, die Folgendes tun könnten:
- optimale Methode zum Festlegen des Inhalts des Listenfelds.
- schnelle Möglichkeit, alle Elemente des Listenfelds auszuwählen.
Wir sind für jedes Feedback und jeden Vorschlag sehr dankbar.
Automatisierung und SkriptingDatenexploration und -visualisierungMac OSBetreff: Optimierung der Aktualisierung des Listenfeldinhalts.Wie viele Elemente erwarten Sie in der Listbox? Für 1 gibt es << Set Items(), das Sie verwenden können
Bearbeiten:
Betreff: Optimierung der Aktualisierung des Listenfeldinhalts.Hallo Jarmo,
Danke für die Antwort, ich werde versuchen, << Set Items() zu verwenden und werde prüfen, ob es schneller ist als <
Was die Anzahl der Elemente betrifft, so liegt sie bei etwa 30.000. Das Merkwürdige ist, dass es beim Laden des Skripts viel weniger Zeit in Anspruch nimmt, die Liste von Grund auf neu zu füllen, als Inhalte zu aktualisieren. Ich dachte an eine Methode, bei der die Listenfelder gelöscht und dann erneut erstellt werden, aber es dürfte recht schwierig sein, alle diese Änderungen in den Skripten vorzunehmen.
Betreff: Optimierung der Aktualisierung des Listenfeldinhalts.Beide Methoden fühlen sich meiner Meinung nach ziemlich schnell an
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();Betreff: Optimierung der Aktualisierung des Listenfeldinhalts.Beachten Sie, dass << Set Selected standardmäßig das mit dem Listenfeld verknüpfte Skript ausführt (sofern vorhanden). Wenn Sie ein Skript verknüpft haben, es aber nicht bei jedem Satz auslösen möchten, verwenden Sie << Set Selected(idx, 1, Run Script(0)) (Sie können es bei Bedarf beim letzten Satz auslösen).
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();
Betreff: Optimierung der Aktualisierung des Listenfeldinhalts.Vielen Dank für die Demonstration. Auf meinem Rechner ist die zweite Methode etwa 5x schneller, und wie Sie sehen, wird die meiste Zeit der ersten Methode für die ausgewählte Schleife aufgewendet.