所以我们正在开发一个信号处理应用程序,PC中有一种特定类型的硬件,并且有一个与之通信的C驱动程序。 应用程序前端/ gui是用JavaFX编写的。我们在使用JavaFX LineChart时遇到了一些问题,我们正在测量电信号频率,并尝试将其绘制在前面提到的LineChart上。
测量循环运行直到收集到1000个样本,我们一直在测试100Hz信号,这意味着获得这1000个样本需要10秒。
有一个单独的'LineChart'线程正在运行并检查(每10ms)是否有新样本可用,如果是这样,它们被添加到LineChart,如果测量线程完成,LineChart线程重置LineChart(清除系列数据)并且过程重新开始。
每一件事情都在第一次~20分钟内运行良好,之后似乎LineChart'减速',看起来好像绘图没有开始时那么快/动态。
我们已经检查了应用程序中的所有内容,但没有发现任何内容,因此我们创建了一个单独的项目,该项目只有LineChart和一个每隔10ms(最多1000个样本)将样本添加到图表的线程。我们观察到了相同的行为,这是如何完成的:
Thread t = new Thread(new Runnable() {
@Override
public void run() {
int iteration = 0;
long start = 0;
long stop = 0;
while (run) {
CountDownLatch latch = new CountDownLatch(1);
start = System.currentTimeMillis();
for (int i = 0; i < 1001; i++) {
double ran = random(50, 105);
final int c = i;
Platform.runLater(() -> {
series.getData().add(new XYChart.Data<>(c, ran));
if (c == 1000) {
System.out.print("Points: " + series.getData().size());
series.getData().clear();
latch.countDown();
}
});
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
iteration++;
stop = System.currentTimeMillis();
try {
latch.await();
} catch (InterruptedException e) {}
System.out.println(", Iteration : " + iteration + ", elapsed: " + (stop - start) + " [ms]");
}
}
});
我们在这里缺少什么?在上面的示例中,为什么性能在~30-45分钟后下降?有什么想法吗?
上面的代码运行了8小时,每次将所有点都添加到图表中,“绘图时间”具有可比性(在10100ms和10350ms之间)。
答案 0 :(得分:0)
这是一个比较老的问题,但是如果有人偶然发现它以寻找性能问题,那么在向系列中添加数据的方式将大受打击。 点应尽可能全部添加到系列中,而不是单独添加。
在上述示例中,如果代码将所有遇到的数据点收集到一个列表中,然后使用addAll调用将其添加到该系列的整个列表中,则性能将会提高。可以基于反复试验来设置addAll调用的频率,以提高美观性能,但用户可以看到的赫兹频率远低于Platform.RunLater试图更新的赫兹频率。
答案 1 :(得分:0)
我找到了原因,这是因为安装了AMD GFX卡的Linux平台缺少硬件加速。 Oracle没有提供硬件支持,因此JavaFX降级到了糟糕的水平,导致性能下降。原始帖子中的代码在Win机器或带有Nvidia卡的Linux机器上没有问题,但在带AMD卡的Linux上则没有问题。在具有AMD卡的Linux上,您必须手动执行软件加速(与默认驱动程序相反)。