简体   繁体   中英

What is the fastest way to convert the following byte array -> collection of class objects

I have a byte array which can contain millions of bytes and is represented by the following structure: The array breaks down into n segments of 16 bytes each. The first 8 bytes of each segment represent a value of type long (8 bytes), followed by 2 values each of type short (2* 4 bytes).

I look for the absolute fastest way to convert the byte array segments into a collection of class objects of the following type:

public class Foo
{
    public long Value1 { get; set; }
    public float Value2 { get; set; }
    public float Value3 { get; set; }

    public Foo(long value1, float value2, float value3)
    {
        Value1 = value1;
        Value2 = value2;
        Value3 = value3;
    }
}

What I have tried done so far was using the BitConverter.ToInt64(...),... but the conversion takes way too long given I have to deal with arrays of sizes in the millions of bytes and several hundred of such arrays.

var collection = new List<Foo>();
        var byteArraySize = byteArray.Count();
        for (var counter = 0; counter < byteArraySize; counter += PacketLength) //Packetlength here is 16
        {
            collection.Add(new Foo(
                               BitConverter.ToInt64(byteArray, counter),
                               BitConverter.ToSingle(byteArray, counter + 8),
                               BitConverter.ToSingle(byteArray, counter + 12)));
        }

Can someone please show me how to apply bit-shift logic to speed up this procedure. Unsafe code, using pointer logic, would also work.

Thanks a lot.

The following codes needs 4.668 seconds to process 1 GiB of data on my machine, out of which 0.028 seconds are spent on converting the data and 4.641 seconds on creating Foo objects. Your original code needs 6.227 seconds.

unsafe Foo[] Load(byte[] buffer, int offset, int length)
{
    fixed (byte* ptr = buffer)
    {
        Data* data = (Data*)(ptr + offset);
        Foo[] result = new Foo[length / sizeof(Data)];
        for (int i = 0; i < result.Length; i++)
        {
            result[i] = new Foo(data);
            data++;
        }
        return result;
    }
}

with

struct Data
{
    public long Value1;
    public float Value2;
    public float Value3;
}

and

class Foo
{
    public long Value1 { get; set; }
    public float Value2 { get; set; }
    public float Value3 { get; set; }

    public unsafe Foo(Data* data)
    {
        Value1 = data->Value1;
        Value2 = data->Value2;
        Value3 = data->Value3;
    }
}

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