折线图性能随时间下降

LineChart performance decrease over time

所以我们正在处理信号处理应用程序,PC 中有一种特定类型的硬件和一个与之通信的 C 驱动程序。 应用程序 frontend/gui 是用 JavaFX 编写的。我们在使用 JavaFX LineChart 时遇到一些问题,我们正在测量电信号频率并尝试将其绘制在上述 LineChart 上。

测量 运行 循环进行,直到收集到 1000 个样本,我们一直在使用 100Hz 信号进行测试,这意味着获取这 1000 个样本需要 10 秒。

有一个单独的 'LineChart' 线程 运行ning 并检查(每 10 毫秒)是否有可用的新样本,如果有,则将这些样本添加到折线图,如果测量线程完成,则折线图线程重置 LineChart(清除系列数据)并重新开始该过程。

前 ~20 分钟每件事 运行 都很好,之后似乎折线图 'slows down',看起来好像绘图不像 fast/dynamic开始。

我们几乎检查了应用程序中的所有内容,但一无所获,因此我们创建了一个单独的项目,其中只有 LineChart 和一个线程,该线程每 10 毫秒向图表添加样本(最多 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 分钟后下降?有什么想法吗?

上面这段代码是运行 8h,每次把所有的点都加到Chart上,'drawing time'是可比较的(在10100ms和10350ms之间)。

我看到的代码你没有任何问题,但是,你继续添加到系列中。我不认为这是代码的问题,但它是机器试图跟上和管理你拥有的所有点,你说 1000 秒,这意味着 20 分钟后,你有 120,000 点存储,被管理,被策划。假设您记录到十分之一的位置,那就是大量的存储空间,而且很有可能,您会发现所有这些信息的处理速度都变慢了。简单来说就是机器搞不定

这是一个较旧的问题,但万一有人偶然发现它是为了寻找性能问题,那么将数据添加到系列中的方式会受到很大影响。 应尽可能一次将点添加到一个系列中,而不是单独添加。

在上面的例子中,如果代码将所有遇到的数据点收集到一个列表中,然后使用 addAll 调用将整个列表添加到系列中,性能将会提高。 addAll 调用的频率可以根据美学性能的试验和错误来设置,但用户可以看到的赫兹远低于 Platform.RunLater 尝试更新的赫兹。

我找到了原因,在 Linux 安装了 AMD GFX 卡的平台上缺少硬件加速。 Oracle 不提供硬件支持,因此 JavaFX 退回到一些糟糕的版本,导致性能下降。来自原始 post 的代码片段在 Win 机器或 Linux 带有 Nvidia 卡的机器上没有问题,但在 Linux 带有 AMD 卡的机器上没有问题。在 Linux 使用 amd 卡时,您必须手动强制执行软件加速(与默认加速相反)。