快速字节复制 C++11
Fast byte copy C++11
我需要转换使用大量字节操作的 C# 应用程序。
一个例子:
public abstract class BinRecord
{
public static int version => 1;
public virtual int LENGTH => 1 + 7 + 8 + 2 + 1; // 19
public char type;
public ulong timestamp; // 7 byte
public double p;
public ushort size;
public char callbackType;
public virtual void FillBytes(byte[] bytes)
{
bytes[0] = (byte)type;
var t = BitConverter.GetBytes(timestamp);
Buffer.BlockCopy(t, 0, bytes, 1, 7);
Buffer.BlockCopy(BitConverter.GetBytes(p), 0, bytes, 8, 8);
Buffer.BlockCopy(BitConverter.GetBytes(size), 0, bytes, 16, 2);
bytes[18] = (byte)callbackType;
}
}
基本上 BitConverter
和 Buffer.BlockCopy
每秒调用 100 次。
有几个 class 继承自上面的基础 class 执行更具体的任务。例如:
public class SpecRecord : BinRecord
{
public override int LENGTH => base.LENGTH + 2;
public ushort num;
public SpecRecord() { }
public SpecRecord(ushort num)
{
this.num = num;
}
public override void FillBytes(byte[] bytes)
{
var idx = base.LENGTH;
base.FillBytes(bytes);
Buffer.BlockCopy(BitConverter.GetBytes(num), 0, bytes, idx + 0, 2);
}
}
我应该研究 C++ 中的什么方法?
在我看来,最好的选择是实际转到 C - 使用 memcpy
复制任何对象的字节。
您的上述代码将 re-written 如下:
void FillBytes(uint8_t* bytes)
{
bytes[0] = (uint8_t)type;
memcpy((bytes + 1), &t, sizeof(uint64_t) - 1);
memcpy((bytes + 8), &p, sizeof(double));
memcpy((bytes + 16), &size, sizeof(uint16_t));
bytes[18] = (uint8_t)callbackType;
}
在这里,我使用uint8_t
、uint16_t
和uint64_t
来替代byte
、ushort
和ulong
类型.
请记住,您的时间戳副本不可移植到 big-endian CPU - 它会截断最低字节而不是最高字节。解决这个问题需要手动复制每个字节,如下所示:
//Copy a 7 byte timestamp into the buffer.
bytes[1] = (t >> 0) & 0xFF;
bytes[2] = (t >> 8) & 0xFF;
bytes[3] = (t >> 16) & 0xFF;
bytes[4] = (t >> 24) & 0xFF;
bytes[5] = (t >> 32) & 0xFF;
bytes[6] = (t >> 40) & 0xFF;
bytes[7] = (t >> 48) & 0xFF;
我需要转换使用大量字节操作的 C# 应用程序。
一个例子:
public abstract class BinRecord
{
public static int version => 1;
public virtual int LENGTH => 1 + 7 + 8 + 2 + 1; // 19
public char type;
public ulong timestamp; // 7 byte
public double p;
public ushort size;
public char callbackType;
public virtual void FillBytes(byte[] bytes)
{
bytes[0] = (byte)type;
var t = BitConverter.GetBytes(timestamp);
Buffer.BlockCopy(t, 0, bytes, 1, 7);
Buffer.BlockCopy(BitConverter.GetBytes(p), 0, bytes, 8, 8);
Buffer.BlockCopy(BitConverter.GetBytes(size), 0, bytes, 16, 2);
bytes[18] = (byte)callbackType;
}
}
基本上 BitConverter
和 Buffer.BlockCopy
每秒调用 100 次。
有几个 class 继承自上面的基础 class 执行更具体的任务。例如:
public class SpecRecord : BinRecord
{
public override int LENGTH => base.LENGTH + 2;
public ushort num;
public SpecRecord() { }
public SpecRecord(ushort num)
{
this.num = num;
}
public override void FillBytes(byte[] bytes)
{
var idx = base.LENGTH;
base.FillBytes(bytes);
Buffer.BlockCopy(BitConverter.GetBytes(num), 0, bytes, idx + 0, 2);
}
}
我应该研究 C++ 中的什么方法?
在我看来,最好的选择是实际转到 C - 使用 memcpy
复制任何对象的字节。
您的上述代码将 re-written 如下:
void FillBytes(uint8_t* bytes)
{
bytes[0] = (uint8_t)type;
memcpy((bytes + 1), &t, sizeof(uint64_t) - 1);
memcpy((bytes + 8), &p, sizeof(double));
memcpy((bytes + 16), &size, sizeof(uint16_t));
bytes[18] = (uint8_t)callbackType;
}
在这里,我使用uint8_t
、uint16_t
和uint64_t
来替代byte
、ushort
和ulong
类型.
请记住,您的时间戳副本不可移植到 big-endian CPU - 它会截断最低字节而不是最高字节。解决这个问题需要手动复制每个字节,如下所示:
//Copy a 7 byte timestamp into the buffer.
bytes[1] = (t >> 0) & 0xFF;
bytes[2] = (t >> 8) & 0xFF;
bytes[3] = (t >> 16) & 0xFF;
bytes[4] = (t >> 24) & 0xFF;
bytes[5] = (t >> 32) & 0xFF;
bytes[6] = (t >> 40) & 0xFF;
bytes[7] = (t >> 48) & 0xFF;