Добавлен Singularity
Здравствуйте.
Анализируя свой код подробнее, стремясь выяснить, что и как работает, хотел бы получить у уважаемых адептов JASS разъяснение важного для меня вопроса о том, как две конструкции JASS обходятся с памятью.
Есть блок кода, который можно впихнуть в любую бибилотеку или область
globals
unit array UnitIndexer // Конечно, даже по меркам vJASS, если написать UnitIndexer[размер_массива_ниже_8191], это будет синтаксический сахар, так как массивы в WarCraft III статические и меньше 8192 ячеек в памяти инициализировать не станут.
integer Indexer_Index = 0
endglobals
function GetUnitIndex takes unit whichUnit returns integer
// Знаю, что не самая оптимальная реализация, но задача этого кода - показать суть дела.
local integer i = 0
loop
exitwhen i > Indexer_Index
if UnitIndexer[i] == whichUnit then
return i
endif
set i = i + 1
endloop
return -1
endfunction
function IsUnitIndexed takes unit whichUnit returns boolean
return GetUnitIndex(whichUnit) >= 0
endfunction
function IndexNewUnit takes unit whichUnit returns nothing
// Не стану показывать проверку на дубликаты и "защиту от дураков", чтобы не усложнять код.
set UnitIndexer[Indexer_Index] = whichUnit
set Indexer_Index = Indexer_Index + 1
endfunction
И есть другой блок кода - иной подход к реализации того же самого
globals
group UnitIndexer = null
endglobals
function IsUnitIndexed takes unit whichUnit returns boolean
return IsUnitInGroup(whichUnit,UnitIndexer)
endfunction
function IndexNewUnit takes unit whichUnit returns nothing
if UnitIndexer == null then
set UnitIndexer = CreateGroup()
endif
call GroupAddUnit(UnitIndexer,whichUnit)
endfunction
Какой способ лучше с точки зрения памяти?
С массивами - понятно, создаётся 8191 экземпляр для хранения ссылки на объект unit.
Группа видится мне динамическим массивом, который аллоцирует и деаллоцирует память по необходимости.
Группа видится мне динамическим массивом, который аллоцирует и деаллоцирует память по необходимости.
Расскажите мне, как на самом деле обстоит дело.
В ожидании ответа,
Singularity, 29.06.2017
Принятый ответ
Странное понимание механики. Не бывает универсального лучшего способа, потому и существуют разные способы для конкретных ситуаций.
А экономить байты и такты процессора, заранее пользуясь интерпретируемым скриптовым языком, это вообще моветон.
А экономить байты и такты процессора, заранее пользуясь интерпретируемым скриптовым языком, это вообще моветон.
Разве массив в WarCraft III не предынициализирует 8192 ячейки памяти (по Вашей формуле, в моём случае он потребляет 8192*4=32768 байт, то есть 32Кб)? Он ведь не динамический.
Нет, он динамический. Исходный размер при создании - 1024. И расширяется на 1024 ячейки по мере доступа вплоть до максимальных 8192.
`
ОЖИДАНИЕ РЕКЛАМЫ...
Чтобы оставить комментарий, пожалуйста, войдите на сайт.
рекурсия нужна в основном в операциях над деревьями и сетями
т.е. там где происходит ветвление
а список как и массив это "прямая дорога" и с ними лучше работать циклами
но при этом забывают упомянуть что это пример того что такое рекурсия
а не пример того в каких ситуациях надо использовать рекурсию
и потом есть толпы джуниоров которые не знают в каких ситуациях рекурсия оправдана
Clamp:
Отредактирован Clamp
Отредактирован nvc123
а стэк вызова забивается при каждом следующем элементе(сложность О(n), тратит n * 4/8 байт)
и размер стека как правило довольно мал
а если список хранится не в оперативной памяти и содержит несколько миллионов элементов то у тебя не хватит оперативки чтобы держать весь этот стек
а писать свою реализацию потоков хранящую стек вызовов на ж.д. только ради того чтобы работать с рекурсией не самая лучшая идея
главный + рекурсии в возврате на несколько шагов назад что используется в деревьях и подобных структурах (например прошлись по 1 ветки, вернулись к развилке и прошлись по другой)
например подсчитать количество файлов не являющихся папками в папке
Отредактирован Doc
Плохо читал, это уже написали оказывается.