Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Fast byte copy C++11

I need to convert C# app which uses extensively bytes manipulation.

An example:

    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;
        }
    }

Basically BitConverter and Buffer.BlockCopy called 100s times per sec.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

There are several classes that inherit from the base class above doing more specific tasks. For example:

    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);
        }
    }

What approach in C++ should I look into?

>Solution :

Best option, in my opinion, is to actually go to C – use memcpy to copy over the bytes of any object.

Your above code would then be re-written as follows:

void FillBytes(uint8_t* bytes)
{
     bytes[0] = (uint8_t)type;
     memcpy((bytes + 1), &(((uint8_t*)(t))[1]), sizeof(uint64_t) - 1);
     memcpy((bytes + 8), &p, sizeof(double));
     memcpy((bytes + 16), &size, sizeof(uint16_t));
     bytes[18] = (uint8_t)callbackType;
}

Here, I use uint8_t, uint16_t, and uint64_t as replacements for the byte, ushort, and ulong types.

Keep in mind, your timestamp copy is not portable to a big-endian CPU – it will cut off the lowest byte rather than the highest. Solving that would require copying in each byte manually, like so:

//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;
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading