Последствия реинициализация массива с изменением длинны.

Программирование на Юнити.

Последствия реинициализация массива с изменением длинны.

Сообщение AlexandrBuryakov 26 янв 2019, 15:16

List не самый производительный массив. (Причину необходимости оптимизировать не обсуждаем.)
По этому принял решение хранить некоторые данные в List, но инициализировать с помощью него обычный массив с фиксированной длинной для повышения производительности.
В определённый момент, иногда реже иногда чаще, в List изменяются, добавляются или удаляются какие то данные. После этого нужно обновить обычный массив.
Я произвожу повторную инициализацию фиксированного массива с новой длинной так:

Синтаксис:
Используется csharp

        //Объявления
        List<Rigidbody> rbList = new List<Rigidbody> ();
        Rigidbody [ ] rbArray;
        int rbMax;

        //Метод инициализации и повторной инициализации
        public void RbArrayReBuf (){

                rbMax = rbList.Count;                           //Максимум rb
                rbArray = new Rigidbody [ rbMax ];              //Создаём массив
                rbList.CopyTo ( rbArray );                      //Копируем в массив

        }

 


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

Основной смыл вопроса в том, не будет ли утечки или ещё какой проблемы от этого способа?

Спасибо.
AlexandrBuryakov
UNец
 
Сообщения: 16
Зарегистрирован: 26 янв 2019, 14:36

Re: Последствия реинициализация массива с изменением длинны.

Сообщение ~AvA~ 26 янв 2019, 20:06

Даже страшно начинать отвечать.. )

Давай всё же не будем обходить стороной и обсудим, какие проблемы с производительностью у листа?
А также подумаем заодно, почему его можно создавать с заданной Capacity, что это решает?
Ответ на этот вопрос в принципе порешает твои проблемы и серьёзно упростит код! )

А то ты спрашиваешь об утечках, при копирровании из листа в массив.. прям .. ну я не знаю, кто-то менее нервный чем я может ответить? :))

P.S: Ты же в курсе, что то, что ты делаешь - это изобретаешь лист?
Аватара пользователя
~AvA~
UNITрон
 
Сообщения: 200
Зарегистрирован: 17 фев 2015, 13:09

Re: Последствия реинициализация массива с изменением длинны.

Сообщение seaman 26 янв 2019, 23:39

Ты же в курсе, что то, что ты делаешь - это изобретаешь лист?

+ 100500
seaman
Адепт
 
Сообщения: 7711
Зарегистрирован: 24 янв 2011, 12:32
Откуда: Самара

Re: Последствия реинициализация массива с изменением длинны.

Сообщение Cr0c 27 янв 2019, 14:28

Лист инпаксулирует внутри массив. Главное отличие листа от массива - это проверка индекса при запросе данных и геттер/сеттер при работе с данными.
Аватара пользователя
Cr0c
Адепт
 
Сообщения: 2946
Зарегистрирован: 19 июн 2015, 13:50

Re: Последствия реинициализация массива с изменением длинны.

Сообщение AlexandrBuryakov 27 янв 2019, 19:20

Спасибо за ответ.)
В каждом FixedUpdate мне нужно производить сравнение и вычисление некоторых параметров элементов между собой.
То есть, если элементов 100, то это ~10000 сравнений и вычислений (не будем учитывать оптимизацию избегающую повторений сравнения).
В таком случае простой массив в цикле будет эффективнее чем лист, разве нет? (Где то читал про то, что лист всё таки менее "лёгкий" чем массив)
Я не супер программист, но видел статью которая приводит пример именно в Unity повышения производительности при убирании всех свойств (как раз геттера и сеттера которые, как я только что узнал, есть в List).
Да и статьи про 10000 вызовов тоже видел, где только сами вызовы сжирают кучу ресурсов, если их неймоверно много.
Переинициализироваться List будет редко, потому ~10000 запросов через геттер излишен.

В общем мне тут нужна максимальная производительность, но лезть в дебри ниже C# врятли смогу. И так боюсь всего этого из-за того, что привык к контролю железа, а тут не с могу понять, что под капотом, всё же PC и микроконтроллеры, как песчинка и луна по количеству процессов.
Если переинициализация никак пагубно не влияет, то тогда спасибо за ответ. Интересная информация.)

P.S. Видимо создание собственного примерного List, последствия возни с микроконтроллерами где всё контролируется и всегда изобретается новый велосипед, ибо ресурсов мало.)
AlexandrBuryakov
UNец
 
Сообщения: 16
Зарегистрирован: 26 янв 2019, 14:36

Re: Последствия реинициализация массива с изменением длинны.

Сообщение Cr0c 27 янв 2019, 23:28

~AvA~ писал(а): его можно создавать с заданной Capacity

Вот же ответ - в готовый массив пихать. А по поводу
AlexandrBuryakov писал(а):Да и статьи про 10000 вызовов тоже видел, где только сами вызовы сжирают кучу ресурсов
это было про Update в скриптах, а не вызовы простых гет/сет. С ними критично будет при 1кк вызовах и более без распараллеливания процесса.
Аватара пользователя
Cr0c
Адепт
 
Сообщения: 2946
Зарегистрирован: 19 июн 2015, 13:50

Re: Последствия реинициализация массива с изменением длинны.

Сообщение lafin 13 фев 2019, 17:20

AlexandrBuryakov писал(а):Я не знаю, что творится при инициализации массива с новой длинной, потому вопрос такой, что может плохого происходить от периодической переинициализации массива с новой длинной? Не будет утечки памяти или ещё чего? И просто интересно как устраивается новая длинна массива в памяти и как переопределяется ссылка на него, если начальный адрес массива изменился из-за изменения длинны которая не позволяет массиву существовать в той области памяти в которой он был, если это конечно так происходит, сразу говорю, нич*рта в этом не смыслю, работал много с микроконтроллерами, а там всё проще и прозрачнее.


1. Поле Rigidbody [ ] rbArray это не сам массив, а переменная, хранящая ссылку на массив. "Инициализации массива новой длиной" у тебя нет. Это вообще невозможно. Длина массивов фиксированная, задаётся при создании и никогда не меняется.

Ты просто создаешь новый массив, копируешь в него элементы из списка и записываешь ссылку на этот новый массив в переменную rbArray, затирая ссылку на старый массив. Если на старый массив ссылок нигде больше не хранится, его когда-нибудь "уничтожит" сборщик мусора.

2. Весь метод RbArrayReBuf можно заменить одной строкой: rbArray = rbList.ToArray();

AlexandrBuryakov писал(а):В таком случае простой массив в цикле будет эффективнее чем лист, разве нет? (Где то читал про то, что лист всё таки менее "лёгкий" чем массив)


Запомни простой принцип - никогда не оптимизировать наугад. Даже так: НИКОГДА НЕ ОПТИМИЗИРОВАТЬ НАУГАД. Иначе могут быть сюрпризы.

Если кто-то где-то в интернете написал, что А быстрее Б, это
- не значит, что так на самом деле;
- не значит, что А быстрее Б сейчас (возможно было 5 лет назад);
- не значит, что А быстрее Б везде (в Net Framework, в Net Core, в Mono может быть по-разному):
- не значит, то А быстрее Б в любых задачах или вариантах использования;
- не значит, что А настолько быстрее Б, что имеет смысл менять Б на А везде;
- ...
- может быть, так оно и есть, но кто ж гарантирует?

1. Если веришь, что оптимизированный вариант будет быстрее, надо взять и сравнить. Тогда ты будешь не верить, а точно знать, быстрее ли он и насколько быстрее. Бывает, что медленнее. Бывает, что да, действительно быстрее, но настолько незначительно, что такое ускорение не стоит усложнения кода, которое для него требуется.

2. Если ты думаешь, что знаешь, что оптимизированный вариант будет быстрее, надо взять и сравнить. Тогда ты будешь не думать, что знаешь, а действительно знать.

Если скорость действительно важна, надо сравнивать варианты между собой и принимать решение по результатам сравнения. Если лень, значит скорость не настолько важна - оставь пока как есть.

Бывает, что скорость не то чтобы прям важна, но хочется попробовать ещё оптимизировать. Просто настроение такое. Почему бы и нет, если хочется. Всё равно надо сравнивать варианты, чтобы не сделать хуже.
lafin
UNец
 
Сообщения: 3
Зарегистрирован: 30 июл 2018, 15:38

Re: Последствия реинициализация массива с изменением длинны.

Сообщение AlexandrBuryakov 22 фев 2019, 19:55

Спасибо за объяснения!
AlexandrBuryakov
UNец
 
Сообщения: 16
Зарегистрирован: 26 янв 2019, 14:36

Re: Последствия реинициализация массива с изменением длинны.

Сообщение Woolf 23 фев 2019, 03:09

Cr0c писал(а):Лист инпаксулирует внутри массив. Главное отличие листа от массива - это проверка индекса при запросе данных и геттер/сеттер при работе с данными.


Нууу.. Теоретически это не так. Правильно сделанный List это не массив, это динамическая структура, к массивам не имеющая отношения. Но технически в сишарп лист реализован именно через массивы, что дурость, конечно, несусветная, ибо на корню убивает все преимущества List, а именно, очень быстрое изменение своих размеров, причем, как увеличение, так и уменьшение, без каких либо сдвигов элементов. Но так есть и с этим приходится жить, понимая, что нативный сишарповский лист лучше не уменьшать, иначе будете иметь проблемы с производительностью. Быстрее новый создать на основе старого.
Разработчик Atom Fishing - Рыбалка на поплавок, донку, нахлыст, блесну в постъядерный период.
Разработчик Atom Fishing II - Первая 3D MMO про рыбалку
Аватара пользователя
Woolf
Адепт
 
Сообщения: 6684
Зарегистрирован: 02 мар 2009, 16:59

Re: Последствия реинициализация массива с изменением длинны.

Сообщение Cr0c 23 фев 2019, 11:56

Woolf писал(а):очень быстрое изменение своих размеров, причем, как увеличение, так и уменьшение, без каких либо сдвигов элементов

LinkedList?
Аватара пользователя
Cr0c
Адепт
 
Сообщения: 2946
Зарегистрирован: 19 июн 2015, 13:50


Вернуться в Скрипты

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 7