Рекурсивный метод можно представить в виде цикла.
Допустим, у нас есть простой метод для перебора чего-либо:
Мы видим, что если на вход передать ноду графа и значение, то мы в итоге найдем нужную ноду, либо вернем null.
Чем плох такой вариант? Дело в том, что каждый вход в метод
Что же делать?
Давайте избавимся от рекурсивного вызова метода. Самый простой вариант это сделать - использовать Stack или Queue:
Из минусов - придется объявить коллекцию, куда мы будем складывать элементы. из плюсов - можно обойти граф любой глубины.
#recursion #code #algorithms
Допустим, у нас есть простой метод для перебора чего-либо:
class Node {
public int value;
public Node[] children;
}
Node FindRecursively(Node root, int value) {
if (root.value == value) return root;
for (int i = 0; i < root.children.Length; ++i) {
var node = FindRecursively(root.children[i], value);
if (node != null) return node;
}
return null;
}Мы видим, что если на вход передать ноду графа и значение, то мы в итоге найдем нужную ноду, либо вернем null.
Чем плох такой вариант? Дело в том, что каждый вход в метод
FindRecursively будет создавать стек под этот метод, т.е. чем больше мы используем в методе всяких переменных, тем быстрее закончится место в нашем стеке, если представить, что граф у нас довольно большой.Что же делать?
Давайте избавимся от рекурсивного вызова метода. Самый простой вариант это сделать - использовать Stack или Queue:
Node Find(Node root, int value) {
var queue = new Queue<Node>();
queue.Enqueue(root);
while (queue.Count > 0) {
var node = queue.Dequeue();
if (node.value == value) return node;
for (int i = 0; i < node.children.Length; ++i) {
queue.Enqueue(node.children[i]);
}
}
return null;
}
Из минусов - придется объявить коллекцию, куда мы будем складывать элементы. из плюсов - можно обойти граф любой глубины.
#recursion #code #algorithms
👍21🔥6🥱2
Когда мы начинали делать проект, в юнити не было возможности отключить Garbage Collector. А нам было нужно)
У нас геймплей был динамичный и любые "провисания" из-за gc плохо влияли на ощущения от игры. Поэтому мы решили его отключить. Раньше для этого нужно было делать хаки, а сейчас уже есть возможность это сделать нормально: https://docs.unity3d.com/Manual/performance-disabling-garbage-collection.html
В нашем кейсе в геймплее мы очень бережно относились (да и относимся) к аллокациям, всё на пулах, поэтому перед началом боя мы выключаем GC, а после боя - включаем и собираем мусор.
Такое решение на самом деле в последствии нам помогло на различных платформах в свое время: на ps4 и switch GC.Collect мог занимать до пары секунд. Надеюсь, что сейчас уже нет таких проблем, но 10 лет назад - были 🙂
#unity #gc
У нас геймплей был динамичный и любые "провисания" из-за gc плохо влияли на ощущения от игры. Поэтому мы решили его отключить. Раньше для этого нужно было делать хаки, а сейчас уже есть возможность это сделать нормально: https://docs.unity3d.com/Manual/performance-disabling-garbage-collection.html
В нашем кейсе в геймплее мы очень бережно относились (да и относимся) к аллокациям, всё на пулах, поэтому перед началом боя мы выключаем GC, а после боя - включаем и собираем мусор.
Такое решение на самом деле в последствии нам помогло на различных платформах в свое время: на ps4 и switch GC.Collect мог занимать до пары секунд. Надеюсь, что сейчас уже нет таких проблем, но 10 лет назад - были 🙂
#unity #gc
🔥33👍7🥱1
Пишите non-alloc методы.
Мы часто пишем подобные методы:
В этом методе мы просто собираем элементы и возвращаем.
При этом создаем список, создание которого мы не можем запретить извне. Для этого лучше писать таким образом:
Таким образом контроль над списком может быть таким:
#gc #code #allocations
Мы часто пишем подобные методы:
List<int> GetItems() {
var items = new List<int>();
...
return items;
}
В этом методе мы просто собираем элементы и возвращаем.
При этом создаем список, создание которого мы не можем запретить извне. Для этого лучше писать таким образом:
void GetItems(List<int> items) {
...
}
Таким образом контроль над списком может быть таким:
var list = GetFromPool();
GetItems(list);
...
ReturnToPool(list);
#gc #code #allocations
👍27🔥6🗿3👎2
Ссылка на запись последнего евента про мультиплеер:
https://youtu.be/nImCndj3F6U
Все, кто хотят меня поддержать, могут это сделать тут:
Евро: NL19 BUNQ 2070 8912 32
Доллары: GB45 TCCL 0414 0434 4305 90
#event #record
https://youtu.be/nImCndj3F6U
Все, кто хотят меня поддержать, могут это сделать тут:
Евро: NL19 BUNQ 2070 8912 32
Доллары: GB45 TCCL 0414 0434 4305 90
#event #record
🔥34👍10❤🔥8⚡1🌚1
В субботу будет тема про джобы, будем разбираться как работают, что там внутри и всякое такое :) Приходите, будет интересно!
https://unsafecsharp.timepad.ru/event/2474487/
#event
https://unsafecsharp.timepad.ru/event/2474487/
#event
🔥29👌3🤓2
Floodfill
Алгоритм заливки. На самом деле ничего нового в нем нет, мы выбираем элемент массива, читаем из него данные и рекурсивно (https://news.1rj.ru/str/unsafecsharp/115) обращаемся к элементу сверху, снизу, справа и слева. Таким образом мы обойдем все элементы, но нам нужно обойти лишь те, которые имеют те же данные, что и наш начальный элемент.
Пример:
Если мы возьмем центральную 5, то результат заливки числом 6 будет таким:
#floodfill #algorithms
Алгоритм заливки. На самом деле ничего нового в нем нет, мы выбираем элемент массива, читаем из него данные и рекурсивно (https://news.1rj.ru/str/unsafecsharp/115) обращаемся к элементу сверху, снизу, справа и слева. Таким образом мы обойдем все элементы, но нам нужно обойти лишь те, которые имеют те же данные, что и наш начальный элемент.
Пример:
77777
77555
75557
75577
77775Если мы возьмем центральную 5, то результат заливки числом 6 будет таким:
77777
77666
76667
76677
77775
Алгоритм используется в различных областях. Например, в графах поиска пути (https://news.1rj.ru/str/unsafecsharp/69) заливка используется для формирования «закрытых областей», чтобы можно было рано выйти при построении пути, если дойти до точки невозможно (области начальной точки не совпадают с конечной).#floodfill #algorithms
👍9🔥1
Разбирая свой гитхаб, вспомнил что когда-то писал такую штуку:
https://github.com/chromealex/TapticEngine
#github
https://github.com/chromealex/TapticEngine
#github
GitHub
GitHub - chromealex/TapticEngine: Taptic Engine with full source code for iOS and Android
Taptic Engine with full source code for iOS and Android - chromealex/TapticEngine
🔥7
Ленивый if
Условие всегда ленивое и хочет побыстрее выйти.
Если v1 будет true, то что там дальше его не будет интересовать:
Таким образом, если у нас есть такой код:
Выглядит хоть и симпатично, но совершенно непроизводительно.
Лучше писать так:
Естественнно нужно понимать, что CalcV2 вызываться не будет, если CalcV1 вернет true, поэтому не нужно на это расчитывать. Но я надеюсь, что вы это знаете :)
#code #performance #basics
Условие всегда ленивое и хочет побыстрее выйти.
Если v1 будет true, то что там дальше его не будет интересовать:
if (v1 == true || v2 == true) {...}
Таким образом, если у нас есть такой код:
var v1 = CalcV1();
var v2 = CalcV2();
if (v1 == true || v2 == true) {...}
Выглядит хоть и симпатично, но совершенно непроизводительно.
Лучше писать так:
if (CalcV1() == true || CalcV2() == true) {...}
Естественнно нужно понимать, что CalcV2 вызываться не будет, если CalcV1 вернет true, поэтому не нужно на это расчитывать. Но я надеюсь, что вы это знаете :)
#code #performance #basics
👍27🥱13🔥8
Catmull rom - это такая кривая, для построения которой нужно знать 4 точки. Особенность заключается в том, что кривая будет проходить через все 4 точки.
На практике мы такое часто используем, т.к. для построения, например, Безье требуются тангенты, расчет которых иногда затруднителен.
#splines #curve #math #catmullrom
На практике мы такое часто используем, т.к. для построения, например, Безье требуются тангенты, расчет которых иногда затруднителен.
#splines #curve #math #catmullrom
🔥15👍4
У нас на интервью был вот такой вопрос одним из последних. Он показывает именно желание думать, если человек не знает на него ответ, конечно.
У вас есть односвязный список и указатель на один из его элементов (не последний), как удалить этот элемент из списка, оставив список целостным? Возможно ли решение за О(1)?
#interview
У вас есть односвязный список и указатель на один из его элементов (не последний), как удалить этот элемент из списка, оставив список целостным? Возможно ли решение за О(1)?
#interview
👍18👎4👌2
Как мы строим пути для юнитов в Mushroom Wars 2.
https://telegra.ph/Kak-my-stroim-puti-dlya-yunitov-06-23
#mushroomwars #pathfinding
https://telegra.ph/Kak-my-stroim-puti-dlya-yunitov-06-23
#mushroomwars #pathfinding
🔥19👍7
Напоминаю, что сегодня встреча, на которой поговорим про джобы. Кто еще не зарегался - велкам)
https://news.1rj.ru/str/unsafecsharp/119
#event
https://news.1rj.ru/str/unsafecsharp/119
#event
Telegram
Unity: Всё, что вы не знали о разработке
В субботу будет тема про джобы, будем разбираться как работают, что там внутри и всякое такое :) Приходите, будет интересно!
https://unsafecsharp.timepad.ru/event/2474487/
#event
https://unsafecsharp.timepad.ru/event/2474487/
#event
🔥9❤2
Запись с последнего урока по Unity Jobs:
https://www.youtube.com/watch?v=Abp_9x8pX-E
Все, кто хотят меня поддержать, могут это сделать тут:
Евро: NL19 BUNQ 2070 8912 32
Доллары: GB45 TCCL 0414 0434 4305 90
#event #record
https://www.youtube.com/watch?v=Abp_9x8pX-E
Все, кто хотят меня поддержать, могут это сделать тут:
Евро: NL19 BUNQ 2070 8912 32
Доллары: GB45 TCCL 0414 0434 4305 90
#event #record
🔥51👍4❤2👏1
Следующий евент пройдет в субботу в 16:00 по мск. Будем обсуждать вёрстку, как верстаются интерфейсы, на что обращать внимание.
Регайтесь, будет интересно :)
https://unsafecsharp.timepad.ru/event/2482334/
#event
Регайтесь, будет интересно :)
https://unsafecsharp.timepad.ru/event/2482334/
#event
🔥34❤2👍2🤔1