C #, возможно ли преобразовать байт * в байт [] без копирования?Какой самый быстрый способ? - PullRequest
3 голосов
/ 27 июля 2011

У меня есть большой байт [] receiveBuffer от соединения с сокетом, который содержит несколько пакетов внутри него.

Я хочу передать отдельные пакеты следующему слою в приложении, но не хочу копировать каждый пакет в новый массив.

В настоящее время я делаю что-то подобное

fixed (byte* rxBufferPtr = receiveBuffer)
{
    while(more_packets_in_rx_buf)
    {
       NewPacketReceived(rxBufferPtr + offset, packetSize);
        // NewPacketReceived params: NewPacketReceived(byte* packet, int size)
       offset += packetSize;
    }
}

Я хотел бы передать управляемый массив вместо указателя и размера, новые параметры NewPacketReceived будут: NewPacketReceived (пакет byte [])

Я никогда не использую приемный буфер, новый создается после его заполнения.

Ответы [ 2 ]

3 голосов
/ 27 июля 2011

Нет, вы не можете без копирования. Передача смещения или длины - путь. Вы не должны быть небезопасными, это не всегда быстрее. Структура ArraySegment может помочь вам передать смещение вместе с массивом.

1 голос
/ 11 августа 2011

"байт * все еще управляемая память"? Я не понимаю это утверждение. byte * - указатель на массив байтов неизвестного размера. Массив управляемых байтов, напротив, имеет известный размер. Управляемый байтовый массив не является указателем памяти (как только у вас есть указатель, данные не могут быть «управляемы» в другую область памяти, так как ваш указатель станет недействительным). Не управляется ли указатель на массив неизвестного размера по определению?

Обратите внимание, что производительность Marshal.Copy низкая (вы можете найти образец тестовой программы, сравнивающий производительность Marshal.Copy с другими методами, использующими вставку имени поисковой машины search). Как правило, вы получаете лучшую производительность копирования, используя ваши собственные итерации и назначения. Выполните присваивание кусками по 64 бита (8 байт), поскольку ЦП может сделать это быстрее, чем побайтовое копирование. Когда байтовый массив не дополняется до 8 байтов, последние несколько байтов должны быть скопированы побайтово.

Опять же, AFAIK, нет способа конвертировать из байта * в байт [] без копии, поэтому основное внимание уделяется созданию неизбежной копии как можно быстрее. Или вы можете найти способ избежать конвертации. Например, работать только в байтах [] или работать только в байтах *. Класс System.Net.Sockets.Socket работает в байте [] - если вы используете этот класс, можете ли вы придерживаться байта [] для тщательного изучения вашего приложения?

...