Asha
Asha

Reputation: 4311

How can I improve performance for converting byte[] to int?

I'm writing a Binary file converter in which I need to convert 1-6 byte arrays into int (short-long) values. At the moment I'm using following three functions, I want to know is there anyway to improve the performance?

private string byteToShortParse(byte[] recordData, int offset, int length)
{
    byte[] workingSet = new byte[2];
    Buffer.BlockCopy(recordData, offset, workingSet, 0, length);
    return (BitConverter.ToInt16(workingSet, 0).ToString());
}

private string byteToIntParse(byte[] recordData, int offset, int length)
{
    byte[] workingSet = new byte[4];
    Buffer.BlockCopy(recordData, offset, workingSet, 0, length);
    return (BitConverter.ToInt32(workingSet, 0).ToString());
}

private string byteToLongParse(byte[] recordData, int offset, int length)
{
    byte[] workingSet = new byte[8];
    Buffer.BlockCopy(recordData, offset, workingSet, 0, length);
    return (BitConverter.ToInt32(workingSet, 0).ToString());
}

Upvotes: 2

Views: 1960

Answers (2)

Yes, optimal variant would be

private string byteToShortParse(byte[] recordData, int offset, int length)
    {
        if (length == 2)
        { 
             short i = (recordData[offset + 1] << 8) | recordData[offset];
             return i.ToString;
        } else return "";

    }

The same applies to 4-byte and 8-byte values (just more shifts are needed).

Upvotes: 1

Marlon
Marlon

Reputation: 20314

Edit2:

I suppose if the number of bytes you need to convert to int is variable length (which does seem strange), I suggest doing it this way:

private string bytesToIntParse(byte[] recordData, int offset, int length)
{
    long result = 0;
    for (int i = 0; i < length; ++i)
    {
        result |= ((long)recordData[i + offset]) << (i * 8);
    }
    return result.ToString();
}

Now you have one function, no Buffer.BlockCopy and it supports any length.

Edit1:

You could use unsafe code such as:

// I don't think you need to specify a length parameter, since int32 is always 4 bytes
private string byteToIntParse(byte[] recordData, int offset, int length)
{
    unsafe
    {
        fixed (byte* p = &recordData[offset])
        {
            // This result will differ on little and big endian architectures.
            return (*(int*)p).ToString();
        }
    }
}

But this is what BitConverter does internally, so I don't think you will gain any performance

Why are you copying the bytes into workingSet? You could just:

return BitConverter.ToInt32(recordData, offset).ToString()

I guess that yields a performance boost since you don't have to call Buffer.BlockCopy every time :P

Upvotes: 1

Related Questions