Форум Flasher.ru
Ближайшие курсы в Школе RealTime
Список интенсивных курсов: [см.]  
  
Специальные предложения: [см.]  
  
 
Блоги Правила Справка Пользователи Календарь Сообщения за день
 

Вернуться   Форум Flasher.ru > Flash > ActionScript 3.0

Версия для печати  Отправить по электронной почте    « Предыдущая тема | Следующая тема »  
Опции темы Опции просмотра
 
Создать новую тему Ответ
Старый 04.11.2014, 19:16
myregmail вне форума Посмотреть профиль Отправить личное сообщение для myregmail Найти все сообщения от myregmail
  № 1  
Ответить с цитированием
myregmail

Регистрация: Mar 2012
Сообщений: 20
По умолчанию Пул объектов

Здравствуйте,
посмотрел в интернете видео урок (трафик ~45МБ), в котором для большого числа объектов рекомендуют применять заранее созданный массив напичканный определенным количеством объектов.
Постараюсь обрисовать (как и в видео) на примере пуль в игре:

Было:
Нажимаем пробел -> создается объект пули и помещается в массив (создается через new())
В цикле игры пули двигаются, когда уходят за экран, их удаляют с экрана обнуляют переменную в массиве и вызывают Garbage Collector

Стало:
Создается массив с заранее забитым числом объектов пуль (также через new()), при нажатии на пробел извлекается доступный элемент массива и помещается на сцену, после ухода за экран он возвращается в этот же массив (на ближайшее свободное место)

Автор уверяет, что этот метод снижает нагрузку на GPU (именно графический процессор) и говорит что именно так и следует поступать с большим числом элементов.

Объясните, пожалуйста, в чем разница создания элементов при необходимости и создании заранее некоторого числа объектов? Ведь они тоже память занимают? Как посчитать разницу в том и другом алгоритме (проверял на 1000 пуль результат нагрузки на процессор тот же)? Прав ли автор или это очередной велосипед для тех кто не умеет правильно Garb.Collector использовать?

Старый 04.11.2014, 19:19
КорДум вне форума Посмотреть профиль Отправить личное сообщение для КорДум Найти все сообщения от КорДум
  № 2  
Ответить с цитированием
КорДум
 
Аватар для КорДум

блогер
Регистрация: Jan 2008
Адрес: syktyvkar
Сообщений: 3,803
Записей в блоге: 10
http://www.flasher.ru/forum/blog.php?b=455
Расписано более чем.
__________________
тут я

Старый 04.11.2014, 20:25
in4core вне форума Посмотреть профиль Отправить личное сообщение для in4core Найти все сообщения от in4core
  № 3  
Ответить с цитированием
in4core
[+4 06.05.14]
 
Аватар для in4core

Регистрация: Mar 2009
Сообщений: 4,219
Записей в блоге: 14
myregmail - сам посуди, если ты хранишь объект и ссылки ты полюбому нагружаешься, как не крути. А если ты их удаляешь , тем более умело снимая все зависимости GC - то должен быть все ок.
Мне кажется вы неверно поняли урок, либо там ересь. Почитайте по ссылке, что привели, может понятнее будет.
__________________
Марк Tween

Старый 04.11.2014, 21:09
Vreden вне форума Посмотреть профиль Отправить личное сообщение для Vreden Найти все сообщения от Vreden
  № 4  
Ответить с цитированием
Vreden
 
Аватар для Vreden

Регистрация: Feb 2009
Сообщений: 141
(урок не смотрел, по ссылкам не ходил).

Про нагрузку на GPU чушь. На GPU будет нагрузка, только, если используется Starling, либо другие фреймворки, использующие Molehill и даже в этом случае нагрузка зависит от количества обсчитываемых объектов на экране и даже при наличии большого количества этих объектов вы быстрее столкнетесь с проблемами памяти, чем с проблемами нагрузки на вычислительные мощности GPU.

Но пул, действительно может помочь снизить нагрузку, только на CPU, ведь создание объекта (new()использует значительные ресурсы процессора. Если объекты часто создаются и удаляются, то нагрузку действительно можно снизить используя пулы. Только изначально первый пул объектов (не использующихся) не забивается под завязку, объекты создаются по мере необходимости. Зачем забивать пул тысячами или сотнями объектов, если за все время работы приложения может понадобится только десять? Пример, нам необходимо создать объект, смотрим в первый пул, если он пуст, то создаем объект new();, если нет, то берем объект из пула и заполняем его свойства необходимыми значениями, помещаем объект во второй пул (использующиеся сейчас объекты), после того как объект стал не нужен, удалили его со сцены, из второго пула и добавили в первый пул и т.д. для следующих объектов.

Таким образом мы сводим создание объектов к минимуму, будет создано ровно столько объектов, сколько использовалось в пик. И объекты будут созданы только тогда, когда это необходимо. Тем самым мы снижаем нагрузку на потребление памяти в моменте и потребление ресурсов процессора при создании объекта и работе GC.

И опять же, совет использовать это для большего числа объектов не состоятелен. Необходимо иметь причину, для того чтобы использовать этот механизм для конкретного типа объекта. Например, создание объекта очень длительный процесс, в сравнении с "простыми"; создание происходит очень часто; большое количество объектов; объект потребляет очень много памяти. Только одно совпадение не может быть причиной для использования этого механизма.

Старый 04.11.2014, 21:59
Gerbert вне форума Посмотреть профиль Найти все сообщения от Gerbert
  № 5  
Ответить с цитированием
Gerbert
Banned
[+1 06.12.14]
[+1 18.12.14]
[+1 30.12.14]

Регистрация: Aug 2014
Сообщений: 461
Цитата:
Про нагрузку на GPU чушь.
Чушь если не выставлен флаг в компиляторе.
Цитата:
Пример, нам необходимо создать объект, смотрим в первый пул, если он пуст, то создаем объект new();, если нет, то берем объект из пула и заполняем его свойства необходимыми значениями, помещаем объект во второй пул (использующиеся сейчас объекты), после того как объект стал не нужен, удалили его со сцены, из второго пула и добавили в первый пул и т.д. для следующих объектов.
Это какой-то "безумный" пул, который на одних splice потратит больше, чем при создании объекта.

Старый 04.11.2014, 22:23
myregmail вне форума Посмотреть профиль Отправить личное сообщение для myregmail Найти все сообщения от myregmail
  № 6  
Ответить с цитированием
myregmail

Регистрация: Mar 2012
Сообщений: 20
КорДум, почитал там о реализации, а об объяснении почему так особо не сказанно. Там еще паттерн iFactory замешан и что-то в ветке обсуждений они ни на чем не сошлись.

Vreden, да используется Starling (извините забыл упомянуть в начале). И при создании пула он передает в него тип объектов в пуле и его длину, т.е. заранее забивая его объектами (с их свойствами и параметрами) - вот это меня и смущает. Ведь если пул сразу забит то и памяти выделено столько же сколько и при создании этого же числа объектов.

Старый 04.11.2014, 23:15
Gerbert вне форума Посмотреть профиль Найти все сообщения от Gerbert
  № 7  
Ответить с цитированием
Gerbert
Banned
[+1 06.12.14]
[+1 18.12.14]
[+1 30.12.14]

Регистрация: Aug 2014
Сообщений: 461
Вы немного не поняли и проверяли видимо не правильно.
Представьте, что Вам каждую секунду нужно создавать сто объектов,
у которых продолжительность жизни тоже секунда. И тут у Вас есть
два варианта -
1) за одну минуту создать шесть тысяч пуль и увеличить нагрузку на .. На cpu..
2) создать сразу или отложено сто пуль и брать их из пула, а потом обратно класть.

То что посоветовал Vreden, это стек, а не пул.

Вам нужно то, что КорДум показал.

И не важно, что в комментах ни к чему не пришли, главное суть можно подчерпнуть.
Пул, как мне кажется, может обойтись и без фабрики, так как он не является хранилищем,
что означает, он может сам создавать и принципы не будут нарушены. И возможно без фабрики
будет лучше, ведь фабрика служит неким подспорьем для смены типа создаваемого объекта,
потому что можно создать интерфейс фабрики, создавать новую фабрику с нужным типом
и передавать её в пул. Но тут смысла мало, возвращенный тип все равно придется кастовать.
По этому, как опять мне кажется, лучше не фабрики создавать, а сделать основной пул и уже расширять
его конкретными пулами с нужным типом. И пусть они создают, это не страшно.

Старый 05.11.2014, 00:03
Zebestov вне форума Посмотреть профиль Отправить личное сообщение для Zebestov Посетить домашнюю страницу Zebestov Найти все сообщения от Zebestov
  № 8  
Ответить с цитированием
Zebestov
Lorem ipsum
 
Аватар для Zebestov

модератор форума
Регистрация: May 2001
Адрес: Одесса
Сообщений: 4,869
Записей в блоге: 4
Позволю небольшую копипасту по теме:

Когда лень делать козырныйпулнавсеслучаижизни, я тулю ленивый пул в пару строк прямо в классе.
Код AS3:
private var _bulletsPool:Array = [];
 
...
 
private function getBullet():Bullet {
   return (this._bulletsPool.length) ? this._bulletsPool.pop() : new Bullet();
}
 
private function putBullet(bullet:Bullet):void {
   this._bulletsPool[this._bulletsPool.length] = bullet;
}
Никаких заморочек, фабрик, превентивного заполнения пула — тупо два метода где-то в конце класса.
__________________
Поймай яблоко 2!

Старый 05.11.2014, 04:08
Vreden вне форума Посмотреть профиль Отправить личное сообщение для Vreden Найти все сообщения от Vreden
  № 9  
Ответить с цитированием
Vreden
 
Аватар для Vreden

Регистрация: Feb 2009
Сообщений: 141
Цитата:
Сообщение от Gerbert Посмотреть сообщение
То что посоветовал Vreden, это стек, а не пул.
Поясните мне, пожалуйста, чем отличается стек от пула?

Цитата:
Сообщение от Gerbert Посмотреть сообщение
Это какой-то "безумный" пул, который на одних splice потратит больше, чем при создании объекта.

Код AS3:
public function Test()
		{
			var array:Array = [];
			for (var i:int = 0; i < 1000; i++)
				array.push(new Sprite());
 
			var time:int = getTimer();
			for (i = 0; i < 100000; i++)
			{
				var sprite:Sprite = array.pop();
				array.push(sprite);
			}	
			trace("Crazy array pool", getTimer() - time); //Crazy pool 28mc
 
			time = getTimer();
			for (i = 0; i < 100000; i++)
				new Shape();
			trace("Create simply display object", getTimer() - time); //Create simply display object 368mc
 
			time = getTimer();
			for (i = 0; i < 100000; i++)
				new Sprite();
			trace("Create simply display object container", getTimer() - time); //Create simply display object container 583mc
		}
Zebestov, то что нужно, я как раз об этом.

Добавлено через 11 минут
Gerbert, ну и для пущей убедительности:

Код AS3:
time = getTimer();
			for (i = 0; i < 100000; i++)
				array[50000];
			trace("Get index without create object", getTimer() - time); //Get index without create object 15mc
500ms минимум изначальной инициализации пула и оверхеда по памяти, против 13 ms на 100000 объектов в динамическом пуле.

Добавлено через 32 минуты
Цитата:
Сообщение от Gerbert Посмотреть сообщение
Чушь если не выставлен флаг в компиляторе.
Даже, если вы компилятору прикажете использовать аппаратное ускорение, но при этом вы не используете stage3d, никакого ускорения вы не получите, это всего-лишь эквивалент wmode=direct при встраивании swf объекта на страницу и опция компилятора предназначена скорее для автономных приложений, как еще один способ разрешить использовать ускорение, что не равно "ускорять и все тут"

Старый 05.11.2014, 07:48
nubideus вне форума Посмотреть профиль Отправить личное сообщение для nubideus Найти все сообщения от nubideus
  № 10  
Ответить с цитированием
nubideus

Регистрация: Jan 2013
Сообщений: 322
Цитата:
Поясните мне, пожалуйста, чем отличается стек от пула?
пул не структура данных. и он может не использовать стек

Создать новую тему Ответ Часовой пояс GMT +4, время: 21:21.
Быстрый переход
  « Предыдущая тема | Следующая тема »  

Теги
алгоритм , оптимизация , память , Сравнение

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.


 


Часовой пояс GMT +4, время: 21:21.


Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2024, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.