Hug*_*lan 12 java performance javafx javafx-8
我一直在努力提高JavaFX中LineChart的性能,但没有取得很大的成功.我也发现这似乎是一些程序员在尝试显示大数据时发现的常见问题(这里的大数据代表数据大于10,000).例如,这种数据在科学和工程中非常普遍,如果我们能够弄清楚如何在JavaFX中加速LineChart,那将会很棒.
好吧,我在stackoverflow中发现了两个帖子,类似的问题JavaFX LineChart的性能问题有65000个数据点和JavaFX LineChart - 绘制数组.主题性能问题的JavaFX线型图有65000个数据点结束了(亚当)建议使用道格拉斯-普克算法!减少进入LineChart的数据点数量以加快速度.
但是,在科学和工程数据中,我们通常需要查看绘图形状,然后放大以查看绘图特定部分的详细信息.因此,如果我们使用Ramer-Douglas-Peucker算法,我们将需要在每次用户放大/缩小时重绘LineChart,我认为这将花费大量处理.
因此,我想知道是否有人在如何加速JavaFX中的LineChart方面有一些提示.这是一个示例代码,包含我到目前为止学到的内容.
import java.util.ArrayList;
import java.util.List;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.chart.LineChart;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
public class TestingLineChart extends Application {
@Override
public void start(Stage primaryStage) {
long startTime, endTime;
startTime = System.nanoTime();
StackPane root = new StackPane();
NumberAxis xAxis = new NumberAxis();
NumberAxis yAxis = new NumberAxis();
LineChart<Number, Number> lineChartPlot = new LineChart<>(xAxis, yAxis);
// set them false to make the plot faster
lineChartPlot.setAnimated(false);
lineChartPlot.setCreateSymbols(false);
List<XYChart.Data<Double, Double>> data = new ArrayList<>();
Scene scene = new Scene(root, 300, 250);
endTime = System.nanoTime();
System.out.println("Time (ms) for creation: " + (endTime - startTime)/1e6);
startTime = System.nanoTime();
for (int n = 0; n < 1e5; n++) {
data.add(new XYChart.Data(n, Math.random()));
}
endTime = System.nanoTime();
System.out.println("Time (ms) for adding data: " + (endTime - startTime)/1e6);
startTime = System.nanoTime();
XYChart.Series dataSeries = new XYChart.Series<>();
dataSeries.setName("data"); // taking the data
dataSeries.getData().addAll(data); // taking the data
endTime = System.nanoTime();
System.out.println("Time (ms) for adding data to series: " + (endTime - startTime)/1e6);
startTime = System.nanoTime();
lineChartPlot.getData().add(dataSeries);
endTime = System.nanoTime();
System.out.println("Time (ms) for adding data to LineChart: " + (endTime - startTime)/1e6);
startTime = System.nanoTime();
root.getChildren().add(lineChartPlot);
endTime = System.nanoTime();
System.out.println("Time (ms) for adding LineChart StackPane: " + (endTime - startTime)/1e6);
startTime = System.nanoTime();
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.show();
endTime = System.nanoTime();
System.out.println("Time (ms) for showing: " + (endTime - startTime)/1e6);
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,如果您运行此代码,最大的成本是渲染,我无法使用这些时间捕获.那么,在我看来,改进应该集中在那里,但我不知道如何.
谢谢.
Eli*_*nko 12
我还将JavaFX图表用于具有数十个数据点的科学应用程序,并且能够实现更新和绘制图形的实时速度.您需要做两件事.
首先,我认为Ramer-Douglas-Peucker算法是不必要的复杂.假设您正在使用一个简单的连续函数,则更容易观察到我们只有有限的显示分辨率,并且对于域中的每个像素,我们不需要多于三个或四个数据点来传达尽可能多的信息尽可能.例如,第一个和最后一个数据点各一个出现在一个像素内,一个数据点用于像素内的最大值和最小值.
您可以尝试这种策略的一些变化,但基本的想法只是一个很好的快速单通道下采样,它应该基本上是无损的.(或者更确切地说,它应该在光栅化之外不会增加任何额外的代表性损失.)它还将点数限制为可管理的东西,并且根据我的经验,它足以快速重绘缩放或实时数据更新.但是,如果您有HiDPI的显示缩放或者出于任何原因缩放图形组件,它可能会导致问题.
第二部分同样重要:即使您将css设置为不绘制数据点形状,仍然需要花费不可思议的长时间将节点添加到场景中.为了解决这个问题,在不希望绘制形状的情况下,LineChart将该dataItemAdded方法子类化并重写为无操作似乎已足够.您还应该尽可能重新使用已添加到系列中的数据点,而不是添加新数据点,即prefer series.getData().get(i).setXValue(...)和series.getData().get(i).setYValue(...)to series.setData(...)或series.getData().add(...).
希望这个评论没有白费或来得太晚:
一些性能限制是 JavaFX 实现固有的:即。许多操作是在 JVM 内计算的,而不是被推送到基于 OpenGL 的底层硬件,数据点Nodes在场景图中绘制过大,而不是动态数据减少和使用Canvas......等等。不幸的是,我们发现如果没有final围绕原始 JavaFX ChartAPI 的更大的变通方法(例如API 方法),就无法解决其中的许多问题(和错误)。
因此,我们开发/重新设计(针对我们的内部应用程序)、开源,并且——希望其他人发现它有用或想要做出贡献——在 GitHub 上发布了我们基于 JavaFX 的图表库:
https://github.com/GSI-CS-CO/chart-fx
其主要关注点:在 25 Hz 更新率下对具有数字信号处理应用中常见的 1 万到 500 万个数据点的数据集进行性能优化的实时数据可视化。性能图、示例和文档可在 GitHub 上获得:
https://github.com/GSI-CS-CO/chart-fx/raw/master/docs/pics/chartfx-example1.png https://github.com/GSI-CS-CO/chart-fx/raw /master/docs/pics/chartfx-performance1a.png https://github.com/GSI-CS-CO/chart-fx/raw/master/docs/pics/chartfx-performance1.png
在 IPAC'19 上介绍了为什么需要新的 JavaFX 库以及与其他基于 Java 和 C++/Qt 的库的性能比较的动机:https ://ipac2019.vrws.de/papers/thprb028.pdf
注意这是我的第一篇文章,因此没有内嵌图片
| 归档时间: |
|
| 查看次数: |
3257 次 |
| 最近记录: |