2014-05-07 3 views
5

Я пытаюсь преобразовать некоторый Java2D-код в JavaFX, и у меня возникла проблема с производительностью JavaFX Canvas. В какой-то момент мне нужно будет нарисовать тысячи маленьких кругов на экране.Задержка Canvas JavaFX

Моя проблема заключается в том, что в первом чертеже мой код занимает много времени для выполнения. Но если мне нужно выполнить второй рисунок, требуется всего лишь небольшая часть времени (он по крайней мере в 10 раз быстрее).

Есть ли что-нибудь, что я делаю неправильно? Есть ли способ предотвратить эту первоначальную задержку?

Я написал этот код, чтобы проверить его. В этом коде я рисую 500 000 кругов в случайных позициях на холсте 1000 x 1000 (построен ранее). Я связал этот код с событием нажатия кнопки, и в первый раз, когда я нажимаю его, требуется 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);   
} 

На самом деле нет максимального количества новых элементов. Он может варьироваться от нескольких сотен до сотен тысяч, в зависимости от потребностей пользователей. И да, это нормально, если некоторые элементы появляются со временем.

+0

Я знаю 500000 ценность там, чтобы продемонстрировать проблему, но сколько в вашем целевом приложении, каково максимальное количество * новых * элементов, которые вам нужны для рисования каждого кадра? Таким образом, ответ может быть лучше адаптирован к вашим конкретным ограничениям. Кроме того, это нормально для приложения, если некоторые элементы «появляются» со временем? – jewelsea

+0

Hi jewelsea. На самом деле нет максимального количества новых элементов. Он может варьироваться от нескольких сотен до сотен тысяч, в зависимости от потребностей пользователей. И да, это нормально, если некоторые элементы появляются со временем. –

+0

Относите [комментарий к списку рассылки разработчиком холста] (http://mail.openjdk.java.net/pipermail/openjfx-dev/2014-May/013838.html). – jewelsea

ответ

1

Ребята Благодарю вас за помощь. Я отправил тот же вопрос в список рассылки OpenJFX, и один из разработчиков ответил. Похоже, что в моей версии JavaFX 2.2 по-прежнему используется старая модель для наращивания командного буфера. В новой версии JavaFX 8 используется более эффективная модель, которая делает первую картину так же быстро, как и последующую.

Вот ответ, который я получил:

Джим Грэхэм (james.graham на оракула.ком)

пн 12 мая 21:17:19 UTC 2014

Это, вероятно, связано с выращиванием командного буфера, который делал линейно в одной точке (вероятно, все еще сделано, что путь в 2.2), но теперь экспоненциальный в 8.0. Первый время рендеринга почти мгновенно в 8.0, но занимает много времени, как вы нашли, когда я пытаюсь его с одним из моих старых 2.x строит ...

 ...jim 
0

я могу думать о паре вещей, но давайте начнем с одного:

Это может быть, что JVM Просто во время компилятор бьет ваше выполнение. Зависит от вашего JVM-варианта (будь то клиент или сервер JIT, и используете ли вы AggresiveOpts или нет).

Помните, что JVM достаточно умен, чтобы выполнять оптимизацию в этом цикле. На мой взгляд, вы можете начать с этого, поместите это на свои параметры JVM при выполнении этого: -XX: + PrintCompilation и посмотрите на вывод на консоли, ваш метод должен быть скомпилирован во время первого выполнения, а затем вы не должны наблюдать компиляции во время второй. Если это так, то вы знаете, что этот кусок кода был скомпилирован и сохранен в CodeCache, а выполнение не выполняется через интерпретатор, а через прямой изначально скомпилированный код, который будет иметь лучшую производительность.

Сообщите нам свои выводы!

параметры виртуальной машины Java ссылка (возможно, потребуется, чтобы найти свой конкретный JVM документ): http://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html

P.S. можете ли вы попытаться снизить время начала, прямо перед тем, как создать экземпляр случайного?, было бы неплохо иметь два раза: один в начале и прямо перед случайным, а второй - сразу после этого последнего времени и, наконец, когда цикл закончен, идея состоит в том, чтобы попытаться разобраться с тем, где ваш код проводит свое время, когда вы это наблюдаете (цикл или создание экземпляра холста).

Смежные вопросы