Для сериализации примитивного массива я задаюсь вопросом, как преобразовать примитив [] в его соответствующий байт []. (т. е. int [128] в байт [512] или пользовательский указатель [] в байт [] ...) Назначением может быть поток памяти, сетевое сообщение, файл, что угодно. Целью является производительность (Сериализация & Время десериализации), чтобы иметь возможность писать с некоторыми потоками байт [] за один кадр, а не зацикливать все значения или выделять с помощью некоторого конвертера.Как преобразовать примитивный [] в байт []
Некоторые уже раствор исследовали:
Regular Loop для записи/чтения
//array = any int[];
myStreamWriter.WriteInt32(array.Length);
for(int i = 0; i < array.Length; ++i)
myStreamWriter.WriteInt32(array[i]);
Это решение работает для сериализации и десериализации И, как в 100 раз быстрее, чем при использовании стандартной System.Runtime.Serialization в сочетании с BinaryFormater для сериализации/десериализации одного int или нескольких из них.
Но это решение становится медленнее, если array.Length содержит более 200/300 значений (для Int32).
В ролях:
Кажется, что C# не может напрямую преобразовать Int [] в байт [] или bool [] в байт [].
BitConverter.Getbytes()
Это решение работает, но он выделяет новые байты [] при каждом вызове цикла через мой междунар []. Спектакли, конечно, ужасно
Marshal.Copy
Да, это решение тоже работает, но та же проблема, как и предыдущие BitConverter один.
C++ взломать
Поскольку прямой бросок не допускается в C#, я судимые некоторые C++ взломать после просмотра в память, что длина массива хранится 4 байта перед началом
ARRAYCAST_API void Cast(int* input, unsigned char** output)
{
// get the address of the input (this is a pointer to the data)
int* count = input;
// the size of the buffer is located just before the data (4 bytes before as this is an int)
count--;
// multiply the number of elements by 4 as an int is 4 bytes
*count = *count * 4;
// set the address of the byte array
*output = (unsigned char*)(input);
}
и данных массива C#, который называют:
byte[] arrayB = null;
int[] arrayI = new int[128];
for (int i = 0; i < 128; ++i)
arrayI[i] = i;
// delegate call
fptr(arrayI, out arrayB);
Я успешно восстановить свою ИНТ [128] в C++, переключите длину массива, и затрагивающий т он имеет правый адрес в моем «output» var, но C# только возвращает байт [1] в качестве возврата. Кажется, что я не могу так легко взломать управляемую переменную.
Итак, я действительно начинаю думать, что все тезисы, которые я хочу достичь, просто невозможны в C# (int [] -> byte [], bool [] -> byte [], double [] -> byte [] ...) без распределения/копирования ...
Что мне не хватает?
Можете ли вы уточнить, что вы пытаетесь сделать? Вы сериализуете массивы? Сериализовать где? HDD может стать вашим настоящим узким местом. И, возможно, вам следует использовать 'byte []' для хранения ваших исходных данных (не нужно сериализовывать то, но получение данных сложно). – Sinatr
Я удивлен, что регулярная петля настолько плоха в производительности. Мне кажется, что это должно быть лучше, и только цикл из двух или трехсот значений сам по себе не похож ни на что, что должно вызывать проблемы с производительностью. Возможно, вам следует исследовать это дальше, а не записывать его как неизбежное влияние производительности. – Chris
Одна заметка на «C++ hack». Я хочу отметить, что вы можете делать возиться с указателями и тэгами в C#, если хотите. Я не делал этого сам, но https://msdn.microsoft.com/en-us/library/f58wzh21(VS.80).aspx может быть отправной точкой, если вы хотите посмотреть на него. Я столкнулся с этим в контексте быстрой обработки растровых данных на изображениях, но при условии, что это также просто манипулирует массивами, это может сработать для вас, если вам действительно нужна производительность. – Chris