读取字节[]的最快(可能是不安全)方式是什么?

时间:2011-03-04 15:12:33

标签: c# multithreading buffer

我正在使用C#中的服务器项目,在收到TCP消息后,它会被解析,并以精确大小的byte []存储。 (不是固定长度的缓冲区,而是存储所有数据的绝对长度的byte []。)

现在读取这个字节[]我将创建一些包装器函数(也用于兼容性),这些是我需要的所有函数的签名:

public byte ReadByte();
public sbyte ReadSByte();
public short ReadShort();
public ushort ReadUShort();
public int ReadInt();
public uint ReadUInt();
public float ReadFloat();
public double ReadDouble();
public string ReadChars(int length);
public string ReadString();

字符串是一个\ 0终止的字符串,可能用ASCII或UTF-8编码,但我无法确定,因为我不是在编写客户端。

数据存在:

byte[] _data;
int _offset;

现在我可以手动编写所有这些函数,如下所示:

public byte ReadByte()
{
    return _data[_offset++];
}

public sbyte ReadSByte()
{
    byte r = _data[_offset++];
    if (r >= 128) return (sbyte)(r - 256);
    else return (sbyte)r;
}

public short ReadShort()
{
    byte b1 = _data[_offset++];
    byte b2 = _data[_offset++];
    if (b1 >= 128) return (short)(b1 * 256 + b2 - 65536);
    else return (short)(b1 * 256 + b2);
}

public short ReadUShort()
{
    byte b1 = _data[_offset++];
    return (short)(b1 * 256 + _data[_offset++]);
}

但我想知道是否有更快的方法,不排除使用不安全的代码,因为这似乎花费了太多时间进行简单的处理。

3 个答案:

答案 0 :(得分:6)

在System命名空间中查看BitConverter类。它包含将byte []的部分转换为其他基本类型的方法。我已经在类似的情况下使用它,并且发现它很快。

对于从byte [] s解码字符串,请使用System.Text命名空间中Encoding类派生的类,特别是GetString(byte[])方法(及其重载)。

答案 1 :(得分:3)

一种方法是将数组的内容映射到结构(假设您的结构确实是静态的):

http://geekswithblogs.net/taylorrich/archive/2006/08/21/88665.aspx

using System;
using System.Runtime.InteropServices;

[StructLayout(LayoutKind.Sequential, Pack=1)]
struct Message
{
    public int id;
    [MarshalAs (UnmanagedType.ByValTStr, SizeConst=50)] 
    public string text;
}

void OnPacket(byte[] packet)
{
    GCHandle pinnedPacket = GCHandle.Alloc(packet, GCHandleType.Pinned);
    Message msg = (Message)Marshal.PtrToStructure(
        pinnedPacket.AddrOfPinnedObject(),
        typeof(Message));        
    pinnedPacket.Free();
}

答案 2 :(得分:1)

您可以使用BinaryReader

BinaryReader是一个流装饰器,因此您必须将byte[]包装在MemoryStream中或将Reader直接连接到网络流。

然后你有

int ReadInt32()
char[] ReadChars(int count)

等。


编辑:显然你想要'更快执行'。

这意味着在通过(网络)I / O接收到这些字节后,您正在寻找byte[]转换的优化。

换句话说,您正在尝试优化仅占用(估计)0.1%时间的部分。完全是徒劳的。