Привет, друзья!
Предлагаю вам игру: Coloroid. Суть проста: у вас есть летающий мячик, отбивающий блоки. Выпустите мячик за пределы сцены - и вы проиграли. Звучит знакомо? Что же, уточнения. Размер летающего мячика - один пиксел. Размер блока - один пиксел. Если вам удается поймать отбитый осколок - он так же превращается в мячик.
Через некоторое время у вас в арсенале несколько тысяч мячиков, а число оставшейся работы уменьшается с завидной скоростью:
В игре есть 100 000 пикселей, которые предстоит разбить. В худшие времена, когда картинка почти вся разобрана по пикселям, а по сцене носятся десятки тысяч мячиков, на моем двухгигагерцевом пеньке FPS не опускается ниже 20. Как же достичь такой скорости?
Вдохновение к этой игре я нашел на сайте wonderfl.net - потрясающий сайт, где собирается много талантливых Flash-разработчиков. Мне нравится копировать оттуда flash работы. Не потому, что я тешу себя фразой Пикассо: "Хорошие художники копируют, великие - воруют". Нет. Просто таким образом ты не только сравниваешь две технологии, но и неизбежно учишь новое. Желаю вам, друзья, легкого профилирования, быстрых программ и неиссякаемого вдохновения!
PS: Исходники к игре я выложил под MS-PL здесь. Вдруг вам будет интересно :).
Предлагаю вам игру: Coloroid. Суть проста: у вас есть летающий мячик, отбивающий блоки. Выпустите мячик за пределы сцены - и вы проиграли. Звучит знакомо? Что же, уточнения. Размер летающего мячика - один пиксел. Размер блока - один пиксел. Если вам удается поймать отбитый осколок - он так же превращается в мячик.
Через некоторое время у вас в арсенале несколько тысяч мячиков, а число оставшейся работы уменьшается с завидной скоростью:
В игре есть 100 000 пикселей, которые предстоит разбить. В худшие времена, когда картинка почти вся разобрана по пикселям, а по сцене носятся десятки тысяч мячиков, на моем двухгигагерцевом пеньке FPS не опускается ниже 20. Как же достичь такой скорости?
Профилирование Silverlight приложений
Профилировать Silverlight приложения можно стандартными средствами Visual Studio 2010.
Проблема лишь в том, что эти стандартные средства не имеют стандартных кнопочек,
чтобы их запустить из IDE. Вместо этого - вооружимся консолью Visual Studio:
Последовательность действий такова. Запускаем консоль VS 2010
(от имени администратора под Vista и выше), и выполняем
команды:
Момент 1. Запускать профайлер нужно именно из той папки, где находятся скомпилированные файлы сильверлайта. Иначе вы не увидите имена функций в файле профайлера:
cd {папка, где находятся скомпилированные Silverlihgt, (не Web!) исходники} VSPerfClrEnv /sampleon "%ProgramFiles%\Internet Explorer\iexplore.exe" {Полный путь к тестoвой страничке SL приложения} VSPerfCmd /start:sample /output:{Имя Файла с результатами профилирования} /attach:{PID процесса iexplore.exe} {Играемся с приложением} VSPerfCmd /detach VSPerfCmd /shutdown VSPerfClrEnv /offВсе, что находится в фигурных скобках, вы заполняете сами и без скобок. В моем случае эта последовательность выглядела так:
cd c:\Projects\Coloroid\Coloroid\Bin\Debug VSPerfClrEnv /sampleon "%ProgramFiles%\Internet Explorer\iexplore.exe" C:\Projects\Coloroid\Coloroid\Bin\Debug\TestPage.html VSPerfCmd /start:sample /output:ProfilingName /attach:8816 Играемся с приложением VSPerfCmd /detach VSPerfCmd /shutdown VSPerfClrEnv /offТройка важных моментов.
Момент 1. Запускать профайлер нужно именно из той папки, где находятся скомпилированные файлы сильверлайта. Иначе вы не увидите имена функций в файле профайлера:
Момент 2.
Если вы запускаете приложение под IE8+, то вы должны указать идентификатор
именно того процесса, в котором запущен Silverlight. Иначе вы будете
профилировать код процесса-контейнера. Определить, какой именно процесс выполняет
Silverlight - легко. Откройте диспетчер задач и поработайте со своим приложением.
Кто загрузит процессор - тот и будет нашим кандидатом.
Момент 3. Как определить идентификатор процесса? - В диспетчере задач зайдите в Вид-> Выбрать столбцы...
Момент 3. Как определить идентификатор процесса? - В диспетчере задач зайдите в Вид-> Выбрать столбцы...
Если все сделано верно, то на выходе мы получим
.vsp файл, который по умолчанию не ассоциирован с 2010-й студией, но легко
открывается в ней. Вот, что получилось у меня:
Сюрприз!
Функция, проверяющая столкнулся ли мячик с доской внизу, занимала львиную долю
вычислений. В чем же дело? Дело в том, что мы часто обращаемся к Dependency
Properties прямоугольника (Width и Height). Это самая
распространенная причина медлительности Silverlight/WPF приложений: использование dependency properties в
интенсивных вычислениях. Решается простым кешированием значений перед выполнением
алгоритма:
/* Где-то в классе Bar */ /* .. */ /// <summary> /// Creates a new instance of <see cref="Bar"/>. /// </summary> /// <param name="barVisual">Visual presentation of the bar.</param> public Bar(Rectangle barVisual) { _barVisual = barVisual; _barVisual.Width = GameSettings.BarWidth; _barWidth = GameSettings.BarWidth; _barHeight = _barVisual.Height; _barTop = GameSettings.SceneHeight - 50; Canvas.SetTop(_barVisual, _barTop); } /// <summary> /// Checks whether point with given coordinates hits the bar. /// </summary> public bool Hit(int x, int y) { // Using _barVisual.Width & _barVisual.Heihgt was a bottleneck. // since they are dependency properties... //return x > _barLeft && x < _barVisual.Width + _barLeft && // y >= _barTop && y < _barTop + _barVisual.Height; return x > _barLeft && x < _barLeft + _barWidth && y >= _barTop && y < _barTop + _barHeight; }
Такое простое изменение позволило увеличить скорость в два раза.
Спасибо!
Вдохновение к этой игре я нашел на сайте wonderfl.net - потрясающий сайт, где собирается много талантливых Flash-разработчиков. Мне нравится копировать оттуда flash работы. Не потому, что я тешу себя фразой Пикассо: "Хорошие художники копируют, великие - воруют". Нет. Просто таким образом ты не только сравниваешь две технологии, но и неизбежно учишь новое. Желаю вам, друзья, легкого профилирования, быстрых программ и неиссякаемого вдохновения!
PS: Исходники к игре я выложил под MS-PL здесь. Вдруг вам будет интересно :).