Практического значения эта задача обычно не имеет (на самом деле применение есть, покажу позже), но, тем не менее, иногда ее дают в качестве учебной задачи. Попробуем ее решить на C#.
Примечание: Создаваемый по умолчанию массив, автоматически заполняется нолями (0x00).
А нам, как раз, наоборот, надо создать массив с паттерном 0xFF или 0xAA.
Я думаю, оно всем понятно. Создать массив и заполнить его нужными значениями:
int items = 536870912;
byte[] tArr = new byte[items];
for (int i = 0; i < items; i++)
{
tArr[i] = 0xFF;
}
Тут мы в цикле присваиваем каждому элементу массива значение 0xFF.
— Оно медленное.
+ Оно простое и с использованием безопасного кода.
Некто попытался оптимизировать прошлое решение, используя Array.Copy(), думая, что эта функция быстрее работает с памятью.
Что решение «в лоб», что «Array.Copy()» с распополамленным циклом работают одинаково, точнее, получилось даже медленнее (в конце статьи будет итоговая таблица):
int items = 536870912;
byte[] tArr = new byte[items];
tArr[0] = 0xFF;
for (int i = 1; i <= items / 2; i *= 2)
{
Array.Copy(tArr, 0, tArr, i, i);
Array.Copy(tArr, 0, tArr, i, items - i);
}
Прямая работа с памятью сильно обходит .NET по скорости, так что самый оптимальный способ для такой задачи — использовать небезопасный код.
public static class FillArray
{
[DllImport("msvcrt.dll",
EntryPoint = "memset",
CallingConvention = CallingConvention.Cdecl,
SetLastError = false)]
private static extern IntPtr MemSet(IntPtr dest, int value, int count);
public static byte[] FillBytes(int Length, byte Value)
{
byte[] Arr = new byte[Length];
GCHandle GCH = GCHandle.Alloc(Arr, GCHandleType.Pinned);
MemSet(GCH.AddrOfPinnedObject(), (int)Value, Length);
return Arr;
}
В свою программу мы импортировали функцию memset из библиотеки msvcrt.dll, т.е. смогли получить контроль над памятью. И заполнили нужным числом массив. Поскольку, за нас это делали библиотеки C++ и функции ОС, все оказалось быстро.
Сравнительная таблица скорости работы разных алгоритмов заполнения массива (массив 500 Мб).
| For | 00:00:04.4212528 |
| For+Array.Copy() | 00:00:04.6952685 |
| MemSet (msvcrt.dll) | 00:00:00.2360135 |
| Random bytes (RNGCryptoServiceProvider) | 00:00:06.1143497 |
Сравнение алгоритмов в источнике.

Тестовый пример (для этого и предыдущего [копия] поста) на GitHub
Pingback: C#, сгенерировать строку нужной длины из одного символа. | Персональный блог Толика Панкова
Pingback: C#, генератор файлов (нужного количества и с определенным содержимым). | Персональный блог Толика Панкова