JRuby, большие массивы и проблемы с производительностью в приложении реального времени - PullRequest
2 голосов
/ 11 мая 2011

Я работаю над игровым приложением в реальном времени.Большая часть написана на Java, но недавно я решил поэкспериментировать с переносом некоторых процедур инициализации в скрипты JRuby, чтобы максимально упростить для игрока изменение способа генерации мира.

Для началаЯ решил перенести генерацию карты в скрипт на JRuby.В настоящее время это сводится к следующему Java-коду:

ScriptingContainer container = new ScriptingContainer();
container.put("$data", dataPackage);
container.runScriptlet(PathType.RELATIVE, scriptName);
dataPackage = (BlockMapGenerationDataPackage)container.get("$data");

Пакет данных содержит всю информацию, необходимую для программы Java для создания конечного ландшафта и его рендеринга, а также содержит необходимые данные взаказ для сценария Ruby, чтобы иметь возможность создавать всевозможные карты.В частности, он содержит довольно большой массив (в настоящее время 1000 x 1000 x 15).Чтобы проверить, работает ли скрипт Ruby, я вычеркнул весь алгоритм генерации карты и поставил следующий чрезвычайно простой тест:

require 'java'
Dir["../../dist/\*.jar"].each { |jar| require jar }

for i in (0...$data.getWidth())
  for j in (0...$data.getDepth())
    $data.blocks[i][j][0] = Java::BlockMap::BlockType::GRASS
  end
end

. Он выполняется только один раз после инициализации.Теперь, когда все это было реализовано в Java с гораздо более интенсивным алгоритмом генерации памяти, не было никаких проблем с производительностью или памятью.Игра шла гладко с сотнями кадров в секунду при очень высоких разрешениях на старом ноутбуке с картой 1000 x 1000 x 15.Однако, когда код генерации Java заменяется приведенным выше сценарием JRuby, программа, похоже, испытывает некоторые проблемы с потреблением памяти: частота кадров падает примерно на 30-40 кадров в секунду, и программа останавливается на 10 секунд с впечатляюще стабильной скоростьюпериодическая скорость примерно один раз каждые три секунды.Профилирование и различные тесты показывают, что единственным возможным виновником является скрипт на Ruby.

Более того, если размер карты резко уменьшится, скажем, до 100 x 100 x 15, эти проблемы более или менее исчезнут.

Я пробовал разные вещи, такие как добавление container.terminate(); или container.clear(); после кода Java для выполнения скрипта, но я действительно не понимаю источник проблемы или как ее исправить.Я был бы очень признателен, если бы кто-то мог объяснить, что здесь происходит не так, и можно ли это исправить!

Ответы [ 2 ]

2 голосов
/ 11 мая 2011

Вы должны хотя бы поэкспериментировать с порядком индексов: [i] [j] [0] по сравнению с [0] [i] [j] и [0] [j] [i].

2 голосов
/ 11 мая 2011

Лучше всего сделать подпрограмму создания карты отдельным приложением, которое связывается с приложением java.

Я почти уверен, что структура памяти массивов в JRuby будет другой, и это может вызвать ваши проблемы - Сам объект карты может быть создан с другой структурой памяти, которая требует некоторого постоянногоВзаимодействие с JRuby, когда к нему обращаются, или это может быть что-то столь же простое, как создание целых чисел вместо целых, и вы не замечаете этого из-за автобокса (опять-таки, ПОЛНОСТЬЮ, так как я не вижу типы данных)

...