Производительность Java ужасна на MacBook с OSX, тем более под Windows на том же устройстве, почему?
Я изучаю Java и начинаю свой первый урок / проект. В этом проекте пиксель репетитора перемещается по экрану и равномерно обрезается и завершает свое путешествие по экрану в течение нескольких секунд. Мой занимает несколько минут, перемещаясь только на 1 пиксель каждые 5 секунд. Я бы подумал, что MacBook Pro будет лучше обрабатывать графику Java. Чтобы увидеть, был ли это мой код или модуль, я перестроил проект с нуля при загрузке в Windows, производительность заметно улучшилась. Там курсор перемещается на 1-2 пикселя в секунду; все еще не так хорошо, как инструкторы, но лучше, чем OSX справляется с этим. Мне интересно, нормально это или ожидаемо? У OSX просто дурное время с обработкой графики Java? Я связал свой код, если он помогает ответить на этот вопрос, а также видео с медленным движущимся пикселем и ужасной частотой кадров в OSX. Фрапс показывает, что я получаю в среднем 650 кадров в секунду в Windows, вывод кода на стороне OSX показывает, что он больше около 40-60 в зависимости от того, запущены ли у меня другие видео процессы. В видео это около 45, но это потому, что захват экрана замедляет его со средних 60 кадров в секунду.
пример частоты кадров в OSX: https://www.youtube.com/watch?v=PQ0-L4slgP4
Код для класса экрана: http://pastebin.com/3ETKsY8r
Код для игрового класса: http://pastebin.com/NDreVB60
Я использую Eclipse Juno под 10.7.5 на стороне Apple и Windows 7 на стороне Bootcamp. MacBook имеет 4 ГБ памяти и 2,53 ГГц Intel Core 2 Duo.
1 ответ
Я запустил ваш пример кода на моем MacBookPro, и результат оказался намного лучше, чем в видео, которое вы опубликовали.
Теперь я не супер эксперт по Java 2D-графике, но заметил, что, поскольку вам нужно перерисовывать весь холст снова и снова с каждой итерацией, чтобы пиксель перемещался, логика, связанная с процессом рендеринга, должна быть быстрой. Кроме того, поскольку пиксель перемещается по диагонали, большая область справа для вашего примера бесполезна, поэтому я бы рекомендовал сделать JFrame квадратом, что уменьшит площадь для повторного рисования.
Наконец, я внес некоторые изменения в код класса Screen, которые могли бы помочь вам быстрее.
package com.oblivion.rain.graphics;
public class Screen {
// Height was removed since there is no use for it
private int width;
public int[] pixels;
int time = 0;
int counter = 0;
// We need this in order to avoid the iteration in the clear method.
int previousPixel = 0;
public Screen(int width, int height) {
this.width = width;
pixels = new int[width * height]; // 50,400
}
public void clear() {
// In case the frame is a rectangle, the previousPixel
// could hold a value that is greater than the array size
// resulting in ArrayOutOfBoundsException
if (previousPixel < pixels.length) {
pixels[previousPixel] = 0;
}
}
public void render() {
counter++;
if (counter % 100 == 0) {
time++;
}
// Calculate the previousPixel index for use in the clear method
previousPixel = time + (time * width);
// Make sure we didn't exceed the array length, then set the
// array data at the calculated index
if (previousPixel < pixels.length) {
pixels[previousPixel] = 0xff00ff;
}
}
}