【问题标题】:JavaFX Canvas delayJavaFX 画布延迟
【发布时间】:2014-05-30 21:22:40
【问题描述】:

我正在尝试将一些 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);        
}

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

【问题讨论】:

  • 我知道 500,000 的值是用来说明问题的,但是在您的目标应用程序中有多少,您需要绘制每帧的 new 元素的最大数量是多少?这样,答案可以更好地适应您的特定限制。另外,如果某些元素随着时间的推移“弹出”,应用程序是否可以?
  • 嗨,jewelsea。实际上没有最大数量的新元素。根据用户的需要,它可以从数百到数十万不等。是的,如果一些元素随着时间的推移出现,那也没关系。
  • 我还没有在javafx 8上测试过。但是,这是否意味着初始延迟是javafx 2.2中的一个错误并且已经在javafx 8.0+中解决了?
  • 所以这个赏金对某人来说很容易获得,他们所要做的就是发布一个答案并引用 Jim Graham 的邮件列表评论。

标签: performance canvas javafx


【解决方案1】:

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

这是我得到的答案:

吉姆·格雷厄姆(james.graham at oracle.com)

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

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

      ...jim

【讨论】:

    【解决方案2】:

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

    可能是 JVM 即时编译器正在执行您的操作。取决于您的 JVM 选项(是客户端 JIT 还是服务器 JIT,以及您是否使用 AggresiveOpts)。

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

    让我们知道您的发现!

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

    附:您可以尝试在实例化随机之前降低开始时间吗?如果能够采取两次,一次在开始时和随机之前,第二次,就在最后一次之后,最后在循环完成后,我们的想法是尝试分解代码在您观察到这一点时花费时间的位置(循环或画布实例化)。

    【讨论】:

      猜你喜欢
      • 2017-05-03
      • 2016-07-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-25
      • 1970-01-01
      相关资源
      最近更新 更多