简体   繁体   中英

C#, Is it possible to convert a byte* to byte[] without a copy? What's the fastest way?

I have a large byte[] receiveBuffer from a socket connection that contains multiple packets inside it.

I want to pass individual packets to the next layer in the application but I don't want to copy each packet into a new array.

I'm currently do something like this

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

I would like to pass a managed array instead of a pointer and size, the new NewPacketReceived params will be: NewPacketReceived(byte[] packet)

I'm never reusing the receive buffer, a new one is created after it's full.

No, you can't without copying. Passing the offset or the length is the way to go. You shouldn't have to go unsafe, it's not always faster. The ArraySegment structure can help you pass the offset along with the array.

"byte* is still managed memory"? I do not understand that statement. byte* is a pointer to an array of bytes of unknown size. A managed byte array on the contrary has a known size. A managed byte array is not a memory pointer (as soon as you have a pointer the data can't be 'managed' to another memory location as your pointer would become invalid). Isn't a pointer to an array of unknown size by definition not managed?

Note that Marshal.Copy performance is poor (you should be able to find sample test program comparing the performance of Marshal.Copy with other techniques using a insert favorite search engine name search). You typically get better performance copying using your own iteration and assignment. Do the assignment by chunks of 64 bits (8 bytes) as the CPU can do that faster than byte by byte copy. When the byte array is not padded to 8 bytes, the last few bytes are to be copied byte by byte.

Again, AFAIK, there is no way to convert from byte* to byte[] without a copy, thus the focus on making the unavoidable copy as fast as possible. Or, you can seek way to avoid converting. For instance, work only in byte[] or work only in byte*. The System.Net.Sockets.Socket class works in byte[] - if you are using that class, can you stick to byte[] thorough your application?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM