2014-05-07 9 views
5

Próbuję przekonwertować kod Java2D do JavaFX i utknąłem z problemem dotyczącym wydajności JavaFX Canvas. W pewnym momencie będę musiał narysować tysiące małych kółek na ekranie.JavaFX Canvas delay

Mój problem polega na tym, że na pierwszym rysunku mój kod zajmuje dużo czasu. Ale jeśli muszę wykonać drugi rysunek, losowanie zajmuje tylko ułamek czasu (jest to co najmniej 10 razy szybciej).

Czy jest coś, co robię źle? Czy istnieje sposób, aby zapobiec temu początkowemu opóźnieniu?

Napisałem ten kod, aby go przetestować. W tym kodzie losuję 500 000 okręgów w losowych pozycjach na płótnie 1000 x 1000 (zbudowanym wcześniej). Połączyłem ten kod ze zdarzeniem kliknięcia przycisku i za pierwszym razem kliknięcie zajmuje 10 sekund. Ale jeśli kliknę ponownie, zajmuje to tylko 0,025 sekundy.

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

W rzeczywistości nie ma maksymalnej liczby nowych elementów. Może się wahać od setek do setek tysięcy, w zależności od potrzeb użytkowników. I tak, jest dobrze, jeśli niektóre elementy pojawiają się z czasem.

+0

Znam 500.000 wartość jest tam, aby zademonstrować problem, ale ile w docelowej aplikacji, jaka jest maksymalna liczba * nowych * elementów potrzebnych do narysowania każdej klatki? W ten sposób odpowiedź może być lepiej dopasowana do twoich szczególnych ograniczeń. Co więcej, czy aplikacja jest w porządku, jeśli niektóre elementy "pojawiają się" w czasie? – jewelsea

+0

Witam jewelsea. W rzeczywistości nie ma maksymalnej liczby nowych elementów. Może się wahać od setek do setek tysięcy, w zależności od potrzeb użytkowników. I tak, jest dobrze, jeśli niektóre elementy pojawiają się z czasem. –

+0

Powiąż [komentarz listy dyskusyjnej autorstwa autora kanwy] (http://mail.openjdk.java.net/pipermail/openjfx-dev/2014-May/013838.html). – jewelsea

Odpowiedz

1

Faceci Dziękuję za pomoc. Wysłałem to samo pytanie na listę mailingową OpenJFX, a jeden z programistów odpowiedział. Wygląda na to, że moja wersja JavaFX 2.2 nadal używa starego modelu do rozbudowy bufora poleceń. Nowa wersja, JavaFX 8, wykorzystuje bardziej wydajny model, który sprawia, że ​​pierwszy obraz jest tak szybki, jak kolejne.

Oto odpowiedź dostałem:

Jim Graham (james.graham w wyroczni.com)

pon 12 maj 2014 21:17:19 UTC

Jest prawdopodobne, ze względu na rosnące bufor poleceń, które zostało zrobione liniowo w jednym punkcie (prawdopodobnie jeszcze zrobić w ten sposób w 2.2), ale jest teraz wykładniczy w 8.0. Po raz pierwszy czyni to prawie chwilowa w 8.0, ale trwa długo, jak znaleźć, gdy próbuję go z jednym z moich starych 2.x buduje ...

 ...jim 
0

Mogę myśleć o kilka rzeczy, ale zacznijmy od jednego:

To może być to, że JVM Just in Time kompilator uderzania wykonanie. Zależy od opcji JVM (czy jest to JIT klienta lub serwera i czy korzystasz z AggresiveOpts, czy nie).

Pamiętaj, że JVM jest wystarczająco inteligentny, aby wykonywać optymalizacje w tej pętli. Moim zdaniem możesz zacząć od tego, umieść to na swoich opcjach JVM podczas wykonywania tego: -XX: + PrintCompilation i spójrz na dane wyjściowe na konsoli, twoja metoda powinna zostać skompilowana podczas pierwszego wykonania, a potem nie powinieneś obserwować żadnych kompilacji podczas drugi. Jeśli tak, to wiesz, że ten fragment kodu został skompilowany i zapisany w CodeCache, a wykonanie nie odbywa się za pośrednictwem interpretera, ale poprzez prosty natywnie skompilowany kod, który będzie miał lepszą wydajność.

Daj nam znać o swoich odkryciach!

opcje JVM odniesienia (może być konieczne, aby znaleźć konkretną JVM doc): http://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html

PS: czy możesz spróbować obniżyć czas rozpoczęcia, zanim napiszesz losowo ?, byłoby miło móc wziąć dwa razy, jeden na początku i tuż przed losowaniem, a drugi, zaraz po tym ostatnim czasie i wreszcie, gdy pętla jest zakończona, chodzi o to, aby spróbować zepsuć miejsce, w którym twój kod spędza swój czas, kiedy to obserwujesz (pętla lub instancja płótna).