Как быстро обнулить массив? - PullRequest
       26

Как быстро обнулить массив?

49 голосов
/ 11 сентября 2009

В настоящее время я делаю это в цикле for, и я знаю, что в C есть API ZeroMemory, однако он не доступен в C #. Также не существует несколько эквивалентного Array.fill из Java. Мне просто интересно, есть ли более простой / быстрый способ?

Ответы [ 6 ]

99 голосов
/ 11 сентября 2009

Попробуйте Array.Clear () :

Устанавливает диапазон элементов в массиве до нуля, до false или до null (Ничего в Visual Basic), в зависимости по типу элемента.

44 голосов
/ 11 сентября 2009
  • C ++: memset(array, 0, array_length_in_bytes);

  • C ++ 11: array.fill(0);

  • C #: Array.Clear(array, startingIndex, length);

  • Java: Arrays.fill(array, value);

15 голосов
/ 11 сентября 2009
Array.Clear(integerArray, 0, integerArray.Length);
11 голосов
/ 11 сентября 2009

Несколько человек опубликовали ответы, а затем удалили их, сказав, что на любом языке цикл for будет одинаково эффективен, как memset, FillMemory и т.

Например, компилятор может разбить его на 64-битные выровненные фрагменты, чтобы воспользоваться 64-битной инструкцией назначения нуля, если она доступна. Это будет принимать во внимание выравнивание и прочее. Реализация Memset, конечно, не тривиальна.

один memset.asm . Также см. memset-is-fast-than-simple-loop.html .

Никогда не стоит недооценивать бесконечную хитрость авторов компиляторов и стандартных библиотек.

10 голосов
/ 03 апреля 2017

UPDATE

Основываясь на бенчмарке , касающемся производительности Array.Clear() и array[x] = default(T), мы можем констатировать, что при обнулении массива необходимо учитывать два основных случая :

A) Существует массив длиной 1,76 элемента ;

B) Существует массив длиной 77 или более элементов .

Таким образом, оранжевая линия на графике представляет Array.Clear() подход.

Линия blue на графике представляет подход array[x] = default(T) (итерация по массиву и установка его значений на default(T)).

enter image description here

Вы можете написать один раз Помощник для выполнения этой работы, например:

public static class ArrayHelper
{
    // Performance-oriented algorithm selection
    public static void SelfSetToDefaults<T>(this T[] sourceArray)
    {
        if (sourceArray.Length <= 76)
        {
            for (int i = 0; i < sourceArray.Length; i++)
            {
                sourceArray[i] = default(T);
            }
        }
        else { // 77+
             Array.Clear(
                 array: sourceArray,
                 index: 0,
                 length: sourceArray.Length);
        }
    }
}

Использование:

someArray.SelfSetToDefaults();
2 голосов
/ 06 июня 2017

Вызов метода с помощью dll import.It быстрый и простой в использовании:)

 [DllImport("msvcrt.dll", EntryPoint = "memset", CallingConvention = CallingConvention.Cdecl, SetLastError = false)]
 public static extern IntPtr MemSet(IntPtr dest, int c, int byteCount);

c - это значение, которое вы хотите установить в памяти

OR

[DllImport("kernel32.dll", EntryPoint="RtlZeroMemory")]
public unsafe static extern bool ZeroMemory(byte* destination, int length);

это только устанавливает данный массив в ноль

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...