![]() |
Общие советы по оптимизации MIDlet Pascal / Java2me программ
Вложений: 1
Прежде всего определимся с направлениями оптимизации мидлета. Этих направлений несколько:
- оптимизация размера готового приложения (JAR файла) - оптимизация использования памяти - оптимизация скорости работы программы - оптимизация переносимости программы Кратко опишу основные советы и рекомендации по оптимизации для каждого направления: 1. Оптимизация по размеру Зачем это нужно? В первую очередь потому, что на некоторых телефонах стоит ограничение на максимальный размер исполнимого JAR файла, к примеру у некоторых моделей телефонов Nokia (40 серии) это ограничение равняется 63 или 127 килобайтам. И эти телефоны отнюдь не пережиток прошлого, они активно продолжают продаваться и распространяться среди пользователей. И объясняй потом какой-нибудь блондинке, почему ваша мега-супер-пупер крутая игра, размером в 150 кб, не пошла на её телефоне, который она покупала исключительно по внешнему виду и низкой цене. К тому же размер важен при загрузке вашей программы из Интернета, не исключено, что программу будут качать прямо на телефоне через мобильный браузер, так что размер программы тут выльется в потраченные рубли и драгоценные секунды ожидания потенциального пользователя вашего шедевра. Самый простой и самый популярный метод уменьшения размеров программы - использование обфускаторов. Таких программ много, вот только краткий список: ProGuard, RetroGuard, JODE... Программы прекрасно справляются с этой функцией, помимо снижения размера повышают и защиту вашего приложения. Следующие методы уже потребуют изменения программы вручную. - избавление от лишних модулей (MIDlet Pascal) или классов (Java2ME). Я понимаю, что с использованием разветвленной системы классов/модулей программа становится короче и понятнее. Увы, это отрицательно сказывается как на размерах готового JAR файла, так и занимаемой оперативной памяти. Поэтому всегда старайтесь объединить несколько классов/модулей в один или вообще отказаться от их использования. В идеале должен быть всего 1 класс/модуль - главный и всё. - Совет чисто для MP - откажитесь от использования специальных типов данных (type), лучше храните все данные в нескольких массивах, чем в одном массиве с особыми типизированными переменными. Такие типизированные переменные занимают очень много оперативной памяти, да и требуется время на извлечение определенного параметра из такой типизированной переменной, а это сказывается на времени работы программы. - выделение часто повторяющихся участков кода в отдельную функцию или процедуру. Если у вас один и тот же код повторяется во многих местах, то есть смысл записать его как процедуру или функцию. - удаление ненужных процедур. если у вас есть процедуры, которые выполняют второстепенную работу (инициализация переменных, отладочный вывод на консоль и проч.) и вызываются только 1 раз - есть смысл избавиться от них вообще, просто перенеся их непосредственный код на место откуда они вызывались. - Если вы часто обращаетесь к какой-то переменной из массива есть смысл записать её значение в локальную переменную и обращаться уже к локальной переменной. Казалось бы какая разница, но локальные переменные читаются быстрее. - не делайте инициализацию больших массивов непосредственно в коде программы. Часто оптимальнее будет хранить значения в текстовом файле, а в коде просто прочитать этот файл и записать прочитанные данные в массив. - Уменьшение размеров графики за счет программ оптимизации графики (pngout, pgcrush) и режимов сжатия. При рисовании графики используйте как можно меньшее количество цветов и сохраняйте графику в сжатых форматах: PNG, JPG, GIF, но не BMP и др. - объединение нескольких графических картинок в один файл. Если у вас в игре куча спрайтов и они хранятся в разных файлах, то лучше их хранить в одном файле в виде пакета спрайтов или на крайний случай просто склейте эти фалы с помощью библиотеки Lib_vault. Один большой файл лучше сжимается, чем куча маленьких. - использовать оптимизированный запаковщик. Не секрет, что JAR файл это обычный ZIP архив, но не многие знают, что параметрами сжатия можно управлять. Часто сжатие проходит по средним параметрам, обеспечивающим быструю распаковку, но не самый маленький размер фала после запаковки. Имеет смысл распаковать содержимое JAR файла и перепаковать его используя более экстремальные параметры сжатия или сторонние архиваторы (к примеру, архиватор kZip сжимает на 5 - 10 килобайт сильнее, чем обычный Zip) 2. Оптимизация использования памяти - Используйте как можно меньше переменных, если это возможно, то используйте другие переменные повторно или временно храните в них какую-то промежуточную информацию - Если ваше приложение работает с какими-то большими массивами или картинками, то лучше загрузить их сразу в начале программы, до объявления других мелких переменных. - Как можно реже делайте создание/удаление объектов. Старайтесь использовать то что уже есть повторно. - Правильно объявляйте массивы. Вы удивитесь, но массив [1..2, 1...1000] займет гораздо меньше памяти, чем массив [1..1000, 1..2]. Просто так происходит из-за выравнивания (alignment) данных в памяти. - Оптимально читайте ресурсы. Для чего используйте специальные библиотеки типа Lib_resload и прочие. Прочитав какую-то информацию тут же закрывайте файл. Дело в том, что на некоторых телефонах при чтении ресурса он сразу весь считывается в оперативную память и занимает её пока вы там что-то читаете построчно или побайтно из файла. То же относится и к сетевым потокам. Не забывайте их закрывать. - Учитывайте особенности некоторых телефонов. К примеру, на некоторых телефонах картинки с прозрачностью занимают памяти намного больше, чем непрозрачные. 3. Оптимизация скорости выполнения программы - используйте более оптимальные алгоритмы. - повыбрасывайте из цикла ненужные повторные действия. - сделайте замеры работы различных процедур и функций, сколько времени выполняется каждая из них. Может быть стОит обращаться к каким-то функциям или процедурам немножко реже? - Грамотно перерисовывайте дисплей. Используйте перерисовку когда она действительно нужна. Если изменилась только какая-то маленькая область, то сделайте перерисовку только этой области, а не всего дисплея. - Как можно реже обращайтесь к RMS. Если у вас в Хранилище Записей хранится какая-то важная для программы информация, то считайте её в переменную, а не обращайтесь каждый раз в RMS, чтобы узнать её значение. - Как можно реже читайте ресурсы. Операции с файлами даже если это внутренние ресурсы программ всегда происходят очень медленно. Лучше сразу считать все ресурсы в переменные в самом начале программы и больше к ресурсам не обращаться вообще. Также вместо того чтобы открывать/закрывать файл каждый раз чтобы что-то там прочитать лучше откройте файл один раз, пометьте его начало (mark) и не закрывайте файл. При последующем обращении к файлу вместо открытия файла просто делайте сброс (reset). Это сэкономит вам много времени. - Используйте многопоточность. Если у вас какая-то процедура часто вызывается может имеет смысл перевести её работу в отдельный поток? 4. Оптимизация переносимости программы Не секрет, что современный парк уже существующих моделей телефонов очень большой и он растет каждую неделю. Поэтому чтобы ваша программа одинаково хорошо работала на большинстве телефонов учитывайте следующее: - учитывайте то, что у всех телефонов разные размеры дисплеев. Поэтому весь вывод графики и работа программы должна идти исходя из полученных программно значений высоты и ширины экрана, а не просто статичных чисел. Пример: FillRect(0, 0, 176, 220) лучше заменить на FillRect(0, 0, GetWidth, GetHeight). - Используйте рисованные шрифты (Lib_font). Их размер и вид вам уже заранее известен, а при использовании стандартных шрифтов не известно какой высоты и ширины будет полученная надпись, да и есть ли данный шрифт в телефоне вообще - на некоторых телефонах есть только 1 шрифт или телефон не имеет поддержки нужных букв (попробуйте запустить программу с русскими надписями на китайском телефоне, скорее всего вы увидите непонятные иероглифы вместо ожидаемых букв). - последнее время появились телефоны с возможностью поворота дисплея сразу во время работы вашей программы. Это тоже нужно учитывать иначе программа будет работать некорректно при повороте и выводить графику не на весь дисплей, а только на часть. - храните все тексты программы в текстовом файле в ресурсах. Если понадобится перевести вашу программу на другой язык нужно будет только перевести 1 файл, а не переделывать всю программу. |
Ответ: Общие советы по оптимизации MIDlet Pascal / Java2me программ
думаю многим это будет полезно))
слушай, а можно подробнее про увеличение скорости выполнения? уж больно низкий порой фпс у меня выходит (1-2 на телефоне, 180-190 на компе если не ограничивать) |
Ответ: Общие советы по оптимизации MIDlet Pascal / Java2me программ
Цитата:
|
Ответ: Общие советы по оптимизации MIDlet Pascal / Java2me программ
ну так речь о дум стори2. там 8 сложений, 6 умножений, 2 деления для отрисовки каждого объекта. переделывать я лучше сам буду.
мне интересно узнать есть ли смысл заменять это на сдвиги (и где почитать о них). что быстрее trunc(i/5); или r/5? большая ли разница запускаем мы процедуру из своего модуля или из другого? |
Ответ: Общие советы по оптимизации MIDlet Pascal / Java2me программ
Разницы из какого модуля что запускается нет. А вот числа лучше использовать только целые. Вычисления с целыми проходят быстрее.
|
Ответ: Общие советы по оптимизации MIDlet Pascal / Java2me программ
а что про сдвиги?
можно ли добиться существенного прироста производительности? (отрисовывается объектов по 700 в сумме, действия над каждым написал выше, а цель - повысить фпс как минимум в 3 раза) |
Ответ: Общие советы по оптимизации MIDlet Pascal / Java2me программ
Наткнулся на статью, откуда взят этот текст.
Кому интересно, вот полный вариант: http://www.dtf.ru/articles/read.php?id=44796 |
Ответ: Общие советы по оптимизации MIDlet Pascal / Java2me программ
Цитата:
|
Ответ: Общие советы по оптимизации MIDlet Pascal / Java2me программ
Цитата:
Скорее всего у тебя видимо очень большая карта с большим количеством объектов на ней. И объекты отрисовываются там наверняка не все, большая часть их находится за пределами видимости. Так вот к чему отрисовывать заведомо невидимый объект? Добавь простейшую проверку будет ли объект виден в окне дисплея и если нет - не отрисовывай его. |
Ответ: Общие советы по оптимизации MIDlet Pascal / Java2me программ
так чтобы проверить надо все равно координаты отсчитать)) а это помним сколько действий
|
Ответ: Общие советы по оптимизации MIDlet Pascal / Java2me программ
700 проверок всё равно быстрее чем 700 отрисовок ;)
|
Ответ: Общие советы по оптимизации MIDlet Pascal / Java2me программ
Жека, на теории и на эмуляторе да, а нокии нет (проверено)
|
Ответ: Общие советы по оптимизации MIDlet Pascal / Java2me программ
Значит сами объекты хранятся не оптимально. Лучше пробегись 1 раз по массиву и посчитай все положения сразу 1 раз и больше к пересчетам не возвращайся.
|
Ответ: Общие советы по оптимизации MIDlet Pascal / Java2me программ
так положений 625. сохранить их = убить нокиа с40
|
Ответ: Общие советы по оптимизации MIDlet Pascal / Java2me программ
Нокиа с40? Не слышал о таком.
|
Ответ: Общие советы по оптимизации MIDlet Pascal / Java2me программ
сериес40 (все что цветное и не смарт)
|
Ответ: Общие советы по оптимизации MIDlet Pascal / Java2me программ
Вот пример участка кода, который отвечает за отрисовку объектов (взято с помощью декомпиляции):
PHP код:
В итоге, после упрощения получим что-то типа такого: PHP код:
Вы вообще слышали, что существуют специальные библиотеки для работы со спрайтами? |
Ответ: Общие советы по оптимизации MIDlet Pascal / Java2me программ
предметов больше чем цифр, вот и перешел на буквы.
выбор шрифта в другом месте стоит, хз почему он у тебя там)) а вот else можно и наставить))) |
Ответ: Общие советы по оптимизации MIDlet Pascal / Java2me программ
Главное ускорение всё же в использовании локальных переменных а и b.
Попробуй хотя бы их добавить в программу, FPS вырастет, я думаю как минимум раза в 2. И используй числа, а не цифры для обозначения типа юнита. 4 миллиардов значений должно хватить. Чего нельзя сказать о цифрах и буквах. |
Ответ: Общие советы по оптимизации MIDlet Pascal / Java2me программ
декомпиль + моя логика видимо помешали твоему восприятию программы.
(i * 60 - j * 4) + l * 6 + 26; считается и так по одному разу для каждого значения i и j перейти на цифры можно, попробую)) а вообще я добился уже 2.5 фпс, чего при пошаговом перемещении хватит (прощитал все деления зарание + более грамотно реализовал задержку) |
Ответ: Общие советы по оптимизации MIDlet Pascal / Java2me программ
а можно еще про kzip поподробнее?
в смысле как им паковать. нормальной инструкции нет + консольными архиваторами не пользовался и еще вопрос о каком именно kzip'е идет речь? есть аналог винзипа для линя с таким названием и консольный на 15кб учитывая сколько я времени потратил на переход на цифры (так и не закончил), прирост менее 10000% считается маленьким... |
Ответ: Общие советы по оптимизации MIDlet Pascal / Java2me программ
kzip сам консольный, весит 15 кб.
Я архивирую так: просто перекидываю все нужные файлы в папку с kzip.exe, потом с консоли ввожу такую команду: PHP код:
|
Ответ: Общие советы по оптимизации MIDlet Pascal / Java2me программ
MidletPascal - 868166 байт
kzip - 868240 байт и правда экономия))) |
Ответ: Общие советы по оптимизации MIDlet Pascal / Java2me программ
Как ты сжимал? У меня твоя прога сжимается так:
Было: 873263 Стало: 864136 А если твои картинки объединить в один пакет, то сжимать будет намного лучше. |
Ответ: Общие советы по оптимизации MIDlet Pascal / Java2me программ
ты жмешь офф версию, с тех пор многое изменилось))
последняя тестовая дала такие результаты) кстати в офф картинки не тронуты, а по тестовой прошелся пнгаутом |
Ответ: Общие советы по оптимизации MIDlet Pascal / Java2me программ
ста, что лучше для экономного расхода памяти:
1. описать глобальную переменную в качестве параметра цикла, которую будут использовать три процедуры. или 2. в каждой из трех процедур описать локальную переменную в качестве параметра цикла. спасибо. , пожалуйттеобъясни |
Ответ: Общие советы по оптимизации MIDlet Pascal / Java2me программ
Могу добавить насчет экономии памяти.
Не следует загружать сразу все ресурсы в память. Обычно это относиться к РПГ играм, так как картинок в РПГ чуть больше, чем дофига. Обычно новички сразу все загружают в память и это - не есть хорошо. Лучше, если загружать только те картинки, которые собираются быть использованными в текущее время и постоянно. Пример: Есть туча изображений монстров и не меньшее количество изображений вещей (иконки). Загружаем изображения монстров (иконки не трогаем) в массив, например, Monsters_image:array [1..50] of image. Ходим, бьем их и т.д. И вдруг нам понадобилось взглянуть в инвентарь. Нам необходимо загрузить иконки. Но перед этим необходимо "очистить" массив Monsters_image. "Очистить" изображения можно, присвоив каждому элементу массива "пустое" изображение. Пример "пустого изображения": null:image; (по умолчанию тип image является одиночным пикселем белого цвета, и занимет 4 байта). Теперь грузим иконки. После того, как игрок вышел из меню инвентаря, таким же способом "очищаем" иконки и загружаем изображения монстров обратно. Плюс: экономия (значительная!) памяти. Минус: Каждый раз при входе и выходе из меню инвентаря на загрузку ресурсов уходит 1-2 секунды (зависит от количества изображений и телефона) |
Ответ: Общие советы по оптимизации MIDlet Pascal / Java2me программ
вопрос: шла речь о "сделайте перерисовку только этой области, а не всего дисплея."
repaint отрисовывает весь экран. как отрисовать именно нужный участок? и еще: как правильнее объявить переменную tmpGlob в таком случае (т.е. результат функции не нужен). использовать глобальную или создать локальную? к глобальной доступ медленнее, локальная - память занимает...... Код:
procedure _light_on; 1) в отличии от делфей, в мидлет паскаль в условии проверяется всегда оба логических выражения, что может приводить к ошибкам: Код:
program a; Код:
for i:=0 to L do ... 3) для циклов быстрее всего выполняется условие Код:
const Код:
while i<=MAXIND do ... Код:
while i<MAXIND+1 do ... |
Ответ: Общие советы по оптимизации MIDlet Pascal / Java2me программ
Может быть и оффтоп, но статья довольно полезная: Игровые циклы или ЭлектроКардиоГама
|
Ответ: Общие советы по оптимизации MIDlet Pascal / Java2me программ
Разве многопоточность увеличит скорость выполнения?
И я так и не понял, в чем плюс локальных переменных? Попробовал - вроде ничего не изменилось |
Ответ: Общие советы по оптимизации MIDlet Pascal / Java2me программ
Цитата:
|
Ответ: Общие советы по оптимизации MIDlet Pascal / Java2me программ
Может увеличить за счет того, что несколько задач выполняются одновременно, каждая в отдельном потоке.
Но вряд ли добавление потоков можно назвать "оптимизацией". |
Ответ: Общие советы по оптимизации MIDlet Pascal / Java2me программ
Хочу музыку в отдельный поток, стоит ли это делать? Выигрыш в скорости выполнения большой будет?
|
Ответ: Общие советы по оптимизации MIDlet Pascal / Java2me программ
На одноядерных процессорах многопоточность не даст прироста в скорости, но иногда это просто удобнее. Да и на многоядерных, чтобы ускорить программу за счет нескольких потоков - надо уметь грамотно распределять между ними задачи.
|
Ответ: Общие советы по оптимизации MIDlet Pascal / Java2me программ
Думаю без потоков можно обойтись. Не такой уж и сложный проект
|
Ответ: Общие советы по оптимизации MIDlet Pascal / Java2me программ
Цитата:
Возможно, я отстал от жизни, и уже всё норм на современных телефонах. |
Ответ: Общие советы по оптимизации MIDlet Pascal / Java2me программ
Отстал) хотя даже крутая трубка может не работать с потоком если не ява машина не поддерживает mixing:)
|
Ответ: Общие советы по оптимизации MIDlet Pascal / Java2me программ
Кто раскроет тайну локальных переменных? я для всех циклов всего 3 переменные использую, это плохо?)
|
Ответ: Общие советы по оптимизации MIDlet Pascal / Java2me программ
Цитата:
Игра была еще до сенсорных, тестировал на 5228, нормально работало. В веселой ферме и музыка играет, и звери звуки издают, нормально работает даже когда на экране месиво из спрайтов :)) У меня просто фоновая музыка, в зависимости от событий откл/запускается новый трек. |
Ответ: Общие советы по оптимизации MIDlet Pascal / Java2me программ
Цитата:
|
Ответ: Общие советы по оптимизации MIDlet Pascal / Java2me программ
Цитата:
|
Ответ: Общие советы по оптимизации MIDlet Pascal / Java2me программ
Цитата:
|
Ответ: Общие советы по оптимизации MIDlet Pascal / Java2me программ
Цитата:
|
Ответ: Общие советы по оптимизации MIDlet Pascal / Java2me программ
Вероятно, разница в скорости от переменных пренебрежительно мала. А вот динамическое создание объектов с последующим удалением их через GarbageCollector - вот это тормоза ощутимые.
|
Ответ: Общие советы по оптимизации MIDlet Pascal / Java2me программ
а setClip() экрана будет полезен перед началом работы? как он вообще работает? у мя часть тайлов выводиться за экраном, ну как и должно быть, для нормального отображения
|
Часовой пояс GMT +4, время: 10:58. |
vBulletin® Version 3.6.5.
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Перевод: zCarot