JavaFX Canvas延迟

时间:2014-05-07 13:09:41

标签: performance canvas javafx

我正在尝试将一些Java2D代码转换为JavaFX,并且我遇到了有关JavaFX Canvas性能的问题。在某些时候,我将不得不在屏幕上绘制数千个小圆圈。

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

我有什么问题吗?有没有办法阻止这种初始延迟?

我写了这段代码来测试它。在这段代码中,我在1000 x 1000画布(之前构建)上的随机位置绘制了500,000个圆圈。我将此代码链接到按钮单击事件,并且在我第一次单击它时需要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);        
}

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

2 个答案:

答案 0 :(得分:1)

伙计们,我感谢你的帮助。我将相同的问题发送到OpenJFX邮件列表,其中一位开发人员回答了问题。似乎我的JavaFX 2.2版本仍然使用旧模型来增长命令缓冲区。新版本JavaFX 8使用了一个更高效的模型,使第一次绘制与后续绘制一样快。

这是我得到的答案:

  

Jim Graham(oracle.com上的james.graham)

     

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

     

这可能是由于增加了已完成的命令缓冲区   线性地在一点(可能仍然在2.2中那样做),但是   现在指数在8.0。第一个渲染时间差不多了   瞬间的   8.0,但是当我用我的旧版本尝试它时,需要很长时间   2.x构建......

      ...jim

答案 1 :(得分:0)

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

可能是JVM Just in Time编译器正在执行。取决于您的JVM选项(无论是客户端还是服务器JIT,以及您是否使用AggresiveOpts)。

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

告诉我们您的发现!

JVM选项参考(可能需要找到您的特定JVM文档): http://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html

P.S。你可以尝试在你实例化随机之前降低开始时间吗?能够两次,一次在开始时和在随机之前,第二次,在最后一次之后,最后当循环完成后,我们的想法是尝试在你观察到它(循环或画布实例化)时花费你的代码来分解你的代码。