Java с беспокойством о производительности - PullRequest
2 голосов
/ 15 ноября 2010

Существует программа, которая генерирует сотни или тысячи движущихся частиц на экране одновременно. После отображения нескольких сотен происходит замедление. Производительность была проанализирована с использованием профилировщика netbeans, и около 80% времени было потрачено на метод рисования в jpanel ... поэтому оптимизация алгоритма вряд ли даст заметную разницу. Можно ли с этим что-то сделать или пришло время подумать о новой платформе? Метод рисования выглядит примерно так:

public void paintComponent(Graphics g) {
    super.paintComponent(g);
    setBackground(Color.WHITE);

    for (int i = 0; i < gameLogic.getParticleArrSize(); i++) {
        g.setColor(gameLogic.getParticleColor(i));
        g.fillOval(gameLogic.getParticleXCoor(i),
                gameLogic.getParticleYCoor(i),
                gameLogic.getParticleSize(i),
                gameLogic.getParticleSize(i));
    }
    g.setColor(gameLogic.getCurrPartColor());
    g.fillOval(mouseX - mouseOvalRadius, mouseY - mouseOvalRadius,
            mouseOvalSize, mouseOvalSize);
    g.setColor(gameLogic.getCursorColor());
    g.fillOval(mouseX - 19, mouseY - 19, 38, 38);

    for (int i = 0; i < gameLogic.getBombArrSize(); i++) {
        g.setColor(Color.RED);
        g.fillOval(gameLogic.getBombXCoor(i) - 6,
                gameLogic.getBombYCoor(i) - 6,
                gameLogic.getBombSize(i),
                gameLogic.getBombSize(i));
    }
    for (int i = 0; i < gameLogic.getPowerUpParticleArrSize(); i++) {
        g.setColor(gameLogic.getPowerUpParticleColor(i));
        g.fillOval(gameLogic.getPowerUpParticleXCoor(i),
                gameLogic.getPowerUpParticleYCoor(i),
                gameLogic.getPowerUpParticleSize(i),
                gameLogic.getPowerUpParticleSize(i));
    }
    for (int i = 0; i < gameLogic.getBlackArrSize(); i++) {
        g.setColor(Color.BLACK);
        g.fillOval(gameLogic.getBlackParticleXCoor(i),
                gameLogic.getBlackParticleYCoor(i),
                gameLogic.getBlackParticleSize(i),
                gameLogic.getBlackParticleSize(i));
    }
}

Ответы [ 3 ]

4 голосов
/ 15 ноября 2010

Когда вы запускаете repaint ()? Это установлено на таймере на некотором временном интервале? Я создал анимационную библиотеку и смог плавно анимировать 40 элементов. Вероятно, у вас есть еще много объектов, но я бы сначала посмотрел на временной интервал.

Редактировать : Итак, вот мое предложение. Для начала вам необходимо выяснить, какая функция краски занимает больше всего времени. Похоже, вы часто звоните fillOval. Мое предложение было бы создать фигуру, используя что-то вроде: new RoundRectangle2D.Double (). А затем используйте AffineTransformation для перемещения по фигурам. Мне любопытно узнать, что другие предлагают, поэтому я проверю еще раз.

3 голосов
/ 16 ноября 2010

Попробуйте изучить библиотеку Graphics2D.Алгоритм заливки для любой фигуры, даже такой простой, как овал, стоит дорого.Намного быстрее создать форму, заполните ее и скопируйте в другие места.2D-библиотека также поддерживает различные преобразования для масштабирования и т. Д.

Это очень похоже на предложение спрайта Даниэля Вионы.Спрайты существуют по определенной причине - это быстрый способ рисовать множество маленьких простых объектов!

Если у меня будет время, я попытаюсь нарисовать тысячи маленьких объектов - старайтесь дать представление о диапазоне размеров этих объектовбуду иметь?Всего несколько пикселей?Я предполагаю, что бонусы и бонусы сравнительно немногочисленны, только частицы причиняют вам боль ...

2 голосов
/ 16 ноября 2010

около 80% времени было потрачено в методе рисования jpanel

Поскольку подавляющее большинство вашей обработки однопоточное, это означает, что по крайней мере одно ядро ​​ЦП работает почтиполностью впустую на современных машинах.В наши дни большинство компьютеров имеют как минимум двухъядерные процессоры, если не больше.Есть несколько способов воспользоваться этим:

  • Если 80% вашего времени тратится на один метод, убедитесь, что оставшиеся 20% не должны ждать, пока картиназавершить.Вычислите следующий кадр заранее, ожидая, пока последний завершит рисование.
  • Ваш метод рисования также можно разбить на несколько потоков.Не безопасно разделять один и тот же объект Graphics между несколькими потоками, но у вас могут быть разные потоки, визуализирующие разные изображения, а затем объединяющие их вместе в конце.
    • Например, один поток занимает первую половинучастиц и рендеринга непосредственно в буферный буфер.Второй поток берет оставшиеся частицы и передает их в изображение.Как только они оба завершатся, добавьте изображение в свой буфер, объединив два изображения.

В качестве бонуса ... Если вы действительно хотите производительность, рассмотрите JOGL.Посмотрите здесь пример:

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...