Обнуление массива
|
|
Valik_Fenko | Дата: Воскресенье, 29 Мая 2016, 13:23 | Сообщение # 1 |
почетный гость
Сейчас нет на сайте
| Как можно обнулить массив быстрее чем циклом?.У меня вот такой массив int [] name = new int[7225]; и мне нужно его обнулить,причем чем быстрее тем лучше. Я нашел такую вещь как Array.Clear,но пишет что такой функции нету..
У меня волновой поиск пути.И нужно типа обнулить сетку от заданых чисел для новых итераций
Сообщение отредактировал Valik_Fenko - Воскресенье, 29 Мая 2016, 13:31 |
|
| |
Левша | Дата: Воскресенье, 29 Мая 2016, 13:38 | Сообщение # 2 |
почти ветеран
Сейчас нет на сайте
| name = new int[];
X.cor.R (Prologue)
Сообщение отредактировал Левша - Воскресенье, 29 Мая 2016, 13:39 |
|
| |
falcoware | Дата: Воскресенье, 29 Мая 2016, 13:53 | Сообщение # 3 |
старожил
Сейчас нет на сайте
| Valik_Fenko, using System; using System.Collections.Generic;
Подключал для: Array.Clear?
|
|
| |
Valik_Fenko | Дата: Воскресенье, 29 Мая 2016, 13:54 | Сообщение # 4 |
почетный гость
Сейчас нет на сайте
| нет.я так и думал что библиотека нид,а вот какая нигде не написано..
|
|
| |
seaman | Дата: Воскресенье, 29 Мая 2016, 13:55 | Сообщение # 5 |
старожил
Сейчас нет на сайте
| name = new int[7225];
|
|
| |
Valik_Fenko | Дата: Воскресенье, 29 Мая 2016, 14:24 | Сообщение # 6 |
почетный гость
Сейчас нет на сайте
| Спс щас буду смотреть какой из них быстрее будет работать =)
Добавлено (29 мая 2016, 14:24) --------------------------------------------- У меня волновой алгоритм пути.Следовательно он неплохо кушает процесор. Мне нужно сделать чтоб был более-менее открытый игровой мир Как можно решить эту проблему?.Я вот думаю сделать вот так: 1.Если юнит переходит в другую локацию(тирейн).Мы перемещаем всю сетку на другой тиррейн и камера будет двигатся ток по этому тиррейну. Сами тиррейны будут на одной сцене а сетку двигать можно относительно координат новой локации.Эт так себе идея.Так что может вы чет лучше придумаете?
Сообщение отредактировал Valik_Fenko - Воскресенье, 29 Мая 2016, 18:14 |
|
| |
Storm54 | Дата: Понедельник, 30 Мая 2016, 12:47 | Сообщение # 7 |
постоянный участник
Сейчас нет на сайте
| Извините, конечно, но пишите вы, товарищи советчики, бред. Array.Clear подходит, но стоит понимать, что он очищает массив так же за O(N), где N - длина массива. Конечно, по производительности этот метод будет чуть быстрее, чем реализация с циклом, но по большому счету разница незначительна, т.к. внутри Clear тот же цикл, только без проверки на out of range при доступе к каждому элементу. new int[N] - вообще идиотское решение. Ладно, если память будет выделена на стеке - аллокация не займет много времени, хотя стоит помнить, что в управляемых языках, коим .NET (и его Mono реализация) и является, каждому элементу массива будет присвоено значение по-умолчанию (в данном случае default(int), т.е. 0). В итоге получаем аллокацию плюс Array.Clear внутри. Оно нам надо? Если же выделение будет происходить в куче, то это попросту приведет к дефрагментации памяти, что в свою очередь снизит производительность. Итог: юзать Array.Clear и стараться лишний раз не выделять память, а заранее создать один большой буфер, который будет использоваться во время всей жизни приложения.
Сообщение отредактировал Storm54 - Понедельник, 30 Мая 2016, 12:52 |
|
| |
seaman | Дата: Понедельник, 30 Мая 2016, 23:49 | Сообщение # 8 |
старожил
Сейчас нет на сайте
| Код using System; using System.Diagnostics;
namespace Test { class Program { static void Main(string[] args) { Stopwatch sw = new Stopwatch(); int[] data = new int[100000];
sw.Start(); Array.Clear(data, 0, data.Length); sw.Stop(); Console.WriteLine("Array.Clear - " + sw.ElapsedTicks);
sw.Reset(); sw.Start(); data = new int[100000]; sw.Stop(); Console.WriteLine("new int[] - " + sw.ElapsedTicks);
sw.Reset(); sw.Start(); for (int i = 0; i < data.Length; i++) data[i] = 0; sw.Stop(); Console.WriteLine("for - " + sw.ElapsedTicks); } } }
А теперь объясните это. Ну и в будущем прежде чем утверждать "идиотское решение" - проверьте или хотя бы покажите свой тест.
|
|
| |
Storm54 | Дата: Вторник, 31 Мая 2016, 12:24 | Сообщение # 9 |
постоянный участник
Сейчас нет на сайте
| Код using System; using System.Diagnostics;
namespace Test { public class Program { private static int[] globalData;
private static void Main() { const int cycles = 100; const int arraySize = 256 * 256;
long clearTicks = 0; long allocTicks = 0;
var sw = new Stopwatch();
globalData = new int[arraySize]; for (var i = 0; i < cycles; i++) { sw.Reset(); sw.Start();
Array.Clear(globalData, 0, globalData.Length);
sw.Stop();
clearTicks += sw.ElapsedTicks; }
for (var i = 0; i < cycles; i++) { sw.Reset(); sw.Start();
globalData = new int[arraySize];
sw.Stop();
allocTicks += sw.ElapsedTicks; }
Console.WriteLine("CLEAR TICKS: " + clearTicks + " ALLOC TICKS: " + allocTicks);
Console.ReadKey(); } } }
Держите. Постарался воспроизвести более-менее реальную ситуацию. Размер массива 256x256 (размер средней карты во многих RTS) Количество итераций 100 (Массив же будет очищаться постоянно)
У меня получились такие результаты:
Ваш тест я считаю некорректным, т.к. показан результат для одной итерации, а выделение памяти происходит на стеке.
Сообщение отредактировал Storm54 - Вторник, 31 Мая 2016, 13:05 |
|
| |
seaman | Дата: Вторник, 31 Мая 2016, 13:10 | Сообщение # 10 |
старожил
Сейчас нет на сайте
| Вот теперь все ясно. По моим тестам. Clear в куче чуток медленнее чем Clear на стеке и практически одинаково с Alloc на стеке (многократном как у Вас). Alloc в куче в два раза медленнее всех предыдущих. Однократный Alloc на стеке (что было в моем первом тесте) значительно быстрее чем все остальное.
|
|
| |
Storm54 | Дата: Вторник, 31 Мая 2016, 13:18 | Сообщение # 11 |
постоянный участник
Сейчас нет на сайте
| Цитата seaman ( ) Alloc в куче в два раза медленнее всех предыдущих. Могу добавить, что время аллокации в куче зависит не только количества выделяемой памяти, а еще и от ее фрагментации, поэтому точно назвать разницу во времени нельзя.
|
|
| |