Performance JavaFX画布延迟

Performance JavaFX画布延迟,performance,canvas,javafx,Performance,Canvas,Javafx,我正在尝试将一些Java2D代码转换为JavaFX,我遇到了一个关于JavaFX画布性能的问题。在某个时刻,我必须在屏幕上画上数千个小圆圈 我的问题是,在第一个图形中,我的代码需要花费很多时间来执行。但是,如果我必须进行第二次绘制,则只需绘制时间的一小部分(至少快10倍) 我做错什么了吗?有没有办法防止最初的延误 我写这段代码是为了测试它。在这段代码中,我在1000 x 1000画布(以前构建)上随机绘制了500000个圆。我将这段代码链接到一个按钮单击事件,第一次单击它需要10秒来执行。但如果

我正在尝试将一些Java2D代码转换为JavaFX,我遇到了一个关于JavaFX画布性能的问题。在某个时刻,我必须在屏幕上画上数千个小圆圈

我的问题是,在第一个图形中,我的代码需要花费很多时间来执行。但是,如果我必须进行第二次绘制,则只需绘制时间的一小部分(至少快10倍)

我做错什么了吗?有没有办法防止最初的延误

我写这段代码是为了测试它。在这段代码中,我在1000 x 1000画布(以前构建)上随机绘制了500000个圆。我将这段代码链接到一个按钮单击事件,第一次单击它需要10秒来执行。但如果我再次点击,只需要0.025秒

private void paintCanvas() {
    long initTime = System.currentTimeMillis();

    GraphicsContext cg = canvas.getGraphicsContext2D();
    cg.setFill(Color.WHITE);
    cg.fillRect(0, 0, canvas.getWidth(), canvas.getHeight());
    cg.setFill(Color.rgb(0, 0, 0, 0.1));

    Random rand = new Random();
    for (int i = 0; i < 500000; i++) {     
        cg.fillOval(1000 * rand.nextFloat(), 1000 * rand.nextFloat(), 2, 2);
    }

    long endTime = System.currentTimeMillis();
    System.out.println("Time spent on drawing:" + (endTime - initTime)/1000.0f);        
}
private void paintCanvas(){
long initTime=System.currentTimeMillis();
GraphicsContext cg=canvas.getGraphicsContext2D();
cg.设置填充(颜色:白色);
cg.fillRect(0,0,canvas.getWidth(),canvas.getHeight());
cg.setFill(Color.rgb(0,0,0,0.1));
Random rand=新的Random();
对于(int i=0;i<500000;i++){
cg.fillOval(1000*rand.nextFloat(),1000*rand.nextFloat(),2,2);
}
long-endTime=System.currentTimeMillis();
System.out.println(“在绘图上花费的时间:”+(endTime-initTime)/1000.0f);
}

实际上,没有新元素的最大数量。根据用户的需要,它可以从几百到几十万不等。是的,随着时间的推移,如果一些元素突然出现,这是可以的。

我可以想到一些事情,但让我们从一个开始:

可能是JVM即时编译器正在影响您的执行。取决于您的JVM选项(是客户机JIT还是服务器JIT,以及您是否在使用侵略性OPTS)

记住,JVM足够聪明,可以在该循环上执行优化。在我看来,您可以从这里开始,在执行此命令时将其放在JVM选项上:-XX:+PrintCompilation,并查看控制台上的输出,您的方法应该在第一次执行期间编译,然后在第二次执行期间不应该观察任何编译。如果是这样的话,那么您就知道这段代码是编译并存储在CodeCache中的,执行不是通过解释器进行的,而是直接通过本机编译的代码进行的,这将具有更好的性能

让我们知道你的发现

JVM选项参考(可能需要查找特定的JVM文档):


另外,你能试着降低开始时间吗?在你实例化random之前,最好能花两次时间,一次在beggining,一次在random之前,第二次在最后一次之后,最后在循环完成时,这样做的目的是,当您观察到这一点(循环或画布实例化)时,尝试对代码花费的时间进行细分。

伙计们,我感谢大家的帮助。我向OpenJFX邮件列表发送了相同的问题,其中一位开发人员回答了这个问题。我的JavaFX2.2版本似乎仍然使用一个旧的模型来增加命令缓冲区。新版本javafx8使用了一个更高效的模型,使得第一幅画的速度与后续的一样快

以下是我得到的答案:

吉姆·格雷厄姆(oracle.com上的詹姆斯·格雷厄姆)

2014年5月12日星期一21:17:19 UTC

这可能是由于增加了已完成的命令缓冲区 在某一点上线性(在2.2中可能仍然是这样),但是 现在是8.0。第一次渲染时间已接近结束 瞬间进入 8.0,但是当我用我的一个老朋友尝试它时,你发现需要很长时间 2.x版本


我知道500000的值是用来演示这个问题的,但是在您的目标应用程序中有多少个,您需要绘制每个帧的新元素的最大数量是多少?这样,答案可以更好地根据您的具体限制进行调整。另外,如果一些元素随着时间的推移“弹出”,应用程序是否可以?嗨,jewelsea。实际上,没有新元素的最大数量。根据用户的需要,它可以从几百到几十万不等。是的,如果一些元素随着时间的推移突然出现是可以的。Relate。我还没有在JavaFX8上测试过它。但是,这是否意味着最初的延迟是JavaFX2.2中的一个缺陷,并且已经在JavaFX8.0+中得到了解决?因此,对于某些人来说,这笔奖金很容易获得,他们所需要做的就是发布一个引用Jim Graham邮件列表评论的回复。
      ...jim