LineChart性能随着时间的推移而降低

时间:2016-04-09 21:04:08

标签: java multithreading performance javafx-2 javafx-8

所以我们正在开发一个信号处理应用程序,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之间)。

2 个答案:

答案 0 :(得分:0)

这是一个比较老的问题,但是如果有人偶然发现它以寻找性能问题,那么在向系列中添加数据的方式将大受打击。 点应尽可能全部添加到系列中,而不是单独添加。

在上述示例中,如果代码将所有遇到的数据点收集到一个列表中,然后使用addAll调用将其添加到该系列的整个列表中,则性能将会提高。可以基于反复试验来设置addAll调用的频率,以提高美观性能,但用户可以看到的赫兹频率远低于Platform.RunLater试图更新的赫兹频率。

答案 1 :(得分:0)

我找到了原因,这是因为安装了AMD GFX卡的Linux平台缺少硬件加速。 Oracle没有提供硬件支持,因此JavaFX降级到了糟糕的水平,导致性能下降。原始帖子中的代码在Win机器或带有Nvidia卡的Linux机器上没有问题,但在带AMD卡的Linux上则没有问题。在具有AMD卡的Linux上,您必须手动执行软件加速(与默认驱动程序相反)。