Среда, 13 Ноября 2024, 12:08

Приветствую Вас Гость

[ Новые сообщения · Игроделы · Правила · Поиск ]
  • Страница 1 из 1
  • 1
Обнуление массива
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 в куче в два раза медленнее всех предыдущих.

Могу добавить, что время аллокации в куче зависит не только количества выделяемой памяти, а еще и от ее фрагментации, поэтому точно назвать разницу во времени нельзя.
  • Страница 1 из 1
  • 1
Поиск:

Все права сохранены. GcUp.ru © 2008-2024 Рейтинг