优化列表框内容更新。大家好,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 循环,显然这是我能找到的唯一一种选择列表框中所有项目的方法,但它的适应行数非常差。
我的问题是,是否有任何最知名的方法来更新列表框的内容,而不会降低性能。我正在寻找可行的替代方案:
- 设置列表框内容的最佳方法。
- 快速选择列表框的所有项目。
如有任何反馈或建议,我们将不胜感激。
自动化和脚本数据探索与可视化苹果系统回复:优化列表框内容更新。您期望列表框中有多少个项目?对于 1,您可以使用 << Set Items()
编辑:
回复:优化列表框内容更新。你好,贾莫,
谢谢您的回复,我将尝试使用 << Set Items() 并检查它是否比 < 更快
至于项目的数量,大约是~30k,奇怪的是,当我加载脚本时,从头开始填充 lb 所需的时间比更新内容所需的时间少得多,我正在考虑一种删除列表框然后再次创建它们的方法,但在脚本中进行所有这些更改可能非常困难。
回复:优化列表框内容更新。我认为这两种方法都相当快
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();回复:优化列表框内容更新。需要注意的一点是,<< 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();
回复:优化列表框内容更新。非常感谢您的演示。在我的计算机上,第二种方法大约快 5 倍,并且您可以看到第一种方法的大部分时间都花在了设置选定循环上。