简体   繁体   English

C#,是否可以在没有副本的情况下将字节*转换为字节[]? 什么是最快的方式?

[英]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. 我有一个来自套接字连接的大字节[] receiveBuffer,其中包含多个数据包。

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) 我想传递托管数组而不是指针和大小,新的NewPacketReceived参数将是: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. ArraySegment结构可以帮助您将偏移量与数组一起传递。

"byte* is still managed memory"? “字节*仍然是托管内存”? I do not understand that statement. 我不明白这个说法。 byte* is a pointer to an array of bytes of unknown size. byte *是指向未知大小的字节数组的指针。 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). 请注意,Marshal.Copy性能很差(您应该能够找到样本测试程序,将Marshal.Copy的性能与使用插入收藏搜索引擎名称搜索的其他技术进行比较)。 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. 通过64位(8字节)的块进行分配,因为CPU可以比逐字节复制更快地完成。 When the byte array is not padded to 8 bytes, the last few bytes are to be copied byte by byte. 当字节数组未填充到8个字节时,最后几个字节将逐字节复制。

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. 同样,AFAIK,没有副本就没有办法从byte *转换为byte [],因此专注于尽可能快地制作不可避免的副本。 Or, you can seek way to avoid converting. 或者,您可以寻求避免转换的方法。 For instance, work only in byte[] or work only in byte*. 例如,仅在byte []中工作或仅在byte *中工作。 The System.Net.Sockets.Socket class works in byte[] - if you are using that class, can you stick to byte[] thorough your application? System.Net.Sockets.Socket类在byte []中工作 - 如果你正在使用那个类,你可以坚持使用你的应用程序的byte []吗?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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