I'm in need to make a byte[] -> T extension method and need it to be fast (no need for it being pretty)
This function will be called 100's of 1000's of times in very short succession in an absolute performance critical environment.
We're currently optimizing on "ticks" level, every tick translates to a couple milliseconds higher in the callstack, thus the need of raw speed over maintainability (not how I like to design software, but the reasoning behind this is out of scope).
Consider the following code, it's clean and maintainable, but it's relatively slow (probably due to boxing and unboxing), Can this be optimized to be faster?
public static T ConvertTo<T>(this byte[] bytes, int offset = 0)
{
var type = typeof(T);
if (type == typeof(sbyte)) return bytes[offset].As<T>();
if (type == typeof(byte)) return bytes[offset].As<T>();
if (type == typeof(short)) return BitConverter.ToInt16(bytes, offset).As<T>();
if (type == typeof(ushort)) return BitConverter.ToUInt32(bytes, offset).As<T>();
if (type == typeof(int)) return BitConverter.ToInt32(bytes, offset).As<T>();
if (type == typeof(uint)) return BitConverter.ToUInt32(bytes, offset).As<T>();
if (type == typeof(long)) return BitConverter.ToInt64(bytes, offset).As<T>();
if (type == typeof(ulong)) return BitConverter.ToUInt64(bytes, offset).As<T>();
throw new NotImplementedException();
}
public static T As<T>(this object o)
{
return (T)o;
}
Nothing can beat the performance of exyi's provided solution. I have no problems with
unsafe
code, but something in the correspondingBitConverter
class methods (http://referencesource.microsoft.com/#mscorlib/system/bitconverter.cs) really concerns me - they do alignment checks and use different implementation for unaligned cases. Below is a much safer pure C# solution - it's probably a little bit slower (but that should be measured, you never know), but should be much faster than the original. As a bonus, I've added explicit name methods (similar to those inBitConverter
) additional to usingbytes.To<int>()
(which is ok, but kind of weird) you can use more convenientbytes.ToInt32()
(which should be faster than generic method).