2014-05-07 8 views
5

Ich versuche, Java2D-Code in JavaFX zu konvertieren, und ich habe ein Problem bezüglich der Leistung von JavaFX Canvas. Irgendwann werde ich Tausende kleiner Kreise auf dem Bildschirm zeichnen müssen.JavaFX Canvas Verzögerung

Mein Problem ist, dass in der ersten Zeichnung mein Code viel Zeit braucht, um ausgeführt zu werden. Aber wenn ich eine zweite Zeichnung machen muss, dauert es nur einen Bruchteil der Zeit zu zeichnen (es ist mindestens 10 mal schneller).

Gibt es irgendetwas, was ich falsch mache? Gibt es eine Möglichkeit, diese anfängliche Verzögerung zu verhindern?

Ich schrieb diesen Code, um es zu testen. In diesem Code zeichne ich 500.000 Kreise an zufälligen Positionen auf einer 1000 x 1000 Leinwand (zuvor gebaut). Ich habe diesen Code mit einem Button-Klick-Ereignis verknüpft, und beim ersten Klicken dauert es 10 Sekunden, bis ich den Befehl ausgeführt habe. Aber wenn ich noch einmal klicke, dauert es nur 0,025 Sekunden.

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);   
} 

Tatsächlich gibt es keine maximale Anzahl neuer Elemente. Abhängig von den Bedürfnissen der Benutzer kann es zwischen einigen Hundert und Hunderttausenden liegen. Und ja, es ist in Ordnung, wenn einige Elemente im Laufe der Zeit auftauchen.

+0

ich die 500.000 kennen Wert ist da, um das Problem zu demonstrieren, aber wie viele in Ihrer Zielanwendung gibt es die maximale Anzahl von * neuen * Elementen, die Sie für jeden Frame benötigen? So kann eine Antwort besser auf Ihre spezifischen Anforderungen zugeschnitten werden. Ist es auch für die App in Ordnung, wenn einige Elemente im Laufe der Zeit "auftauchen"? – jewelsea

+0

Hallo Juwel. Tatsächlich gibt es keine maximale Anzahl neuer Elemente. Abhängig von den Bedürfnissen der Benutzer kann es zwischen einigen Hundert und Hunderttausenden liegen. Und ja, es ist in Ordnung, wenn einige Elemente im Laufe der Zeit auftauchen. –

+0

Relate [Mailinglistenkommentar vom Canvas-Entwickler] (http://mail.openjdk.java.net/pipermail/openjfx-dev/2014-May/013838.html). – jewelsea

Antwort

1

Jungs ich danke Ihnen für die Hilfe. Ich habe die gleiche Frage an die OpenJFX Mailingliste gesendet und einer der Entwickler hat geantwortet. Es scheint, dass meine JavaFX 2.2-Version immer noch ein altes Modell verwendet, um den Befehlspuffer zu vergrößern. Die neue Version, JavaFX 8, verwendet ein effizienteres Modell, das das erste Mal so schnell macht wie die nachfolgenden. Hier

ist die Antwort, die ich bekam:

Jim Graham (james.graham bei Oracle.com)

Mo 12. Mai 21.17.19 UTC 2014

Dies aufgrund der wachsenden die Befehlspuffer wahrscheinlich die linear an einem Punkt (wahrscheinlich noch zu tun, dass die Art und Weise in 2.2) durchgeführt wurde, ist aber jetzt exponentiell in 8.0. Die erste Renderzeit ist fast augenblicklich in 8.0, aber dauert eine lange Zeit, wie Sie gefunden, wenn ich versuche es mit einem meiner alten 2.x baut ...

 ...jim 
0

kann ich von ein paar Dinge denken, aber lassen Sie uns mit einem Start:

es, dass die JVM nur Compiler Ihre Ausführung trifft in der Zeit sein könnte. Hängt von Ihrer JVM-Option ab (ob Client- oder Server-JIT und ob Sie AggressiveOpts verwenden oder nicht).

Denken Sie daran, die JVM ist intelligent genug, um Optimierungen für diese Schleife durchzuführen. Meiner Meinung nach kannst du dort anfangen, setze dies auf deine JVM-Optionen, wenn du dies ausführst: -XX: + PrintCompilation, und schau dir die Ausgabe auf der Konsole an, deine Methode sollte während der ersten Ausführung kompiliert werden und dann solltest du keine Kompilationen beobachten der Zweite. Wenn dies der Fall ist, wissen Sie, dass dieser Codeabschnitt im CodeCache kompiliert und gespeichert wurde. Die Ausführung erfolgt nicht über den Interpreter, sondern über direkt nativ kompilierten Code, der eine bessere Leistung bietet.

Lassen Sie uns Ihre Ergebnisse wissen!

JVM-Optionen Referenz (Möglicherweise müssen Sie bestimmte JVM doc finden): http://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html

P. S. Können Sie versuchen, die Startzeit zu reduzieren, bevor Sie zufällig instanziieren ?, wäre es schön, in der Lage zu sein, zweimal zu nehmen, einer am Anfang und direkt vor dem Zufall, und der zweite, direkt nach diesem letzten Mal und schließlich beim Schleife beendet, die Idee ist zu versuchen, eine Pause zu bekommen, wo Ihr Code es Zeit ist, wenn Sie dies beobachten (die Schleife oder die Leinwand-Instanziierung).