Can you make this code run any faster?
public static class GuidExtensions { public static Guid TransfromToGuidWithProperSorting(this byte[] bytes) { return new Guid(new[] { bytes[10], bytes[11], bytes[12], bytes[13], bytes[14], bytes[15], bytes[8], bytes[9], bytes[6], bytes[7], bytes[4], bytes[5], bytes[0], bytes[1], bytes[2], bytes[3], }); } public static byte[] TransformToValueForEsentSorting(this Guid guid) { var bytes = guid.ToByteArray(); return new[] { bytes[12], bytes[13], bytes[14], bytes[15], bytes[10], bytes[11], bytes[8], bytes[9], bytes[6], bytes[7], bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], }; } }
Just to note, this is stupid micro optimization trick, it takes 0.00008 ms to execute right now, which is plenty fast enough, but it is fun to play with it.
Comments
public Guid(int a, short b, short c, byte d, byte e, byte f, byte g, byte h, byte i, byte j, byte k)
Is the ctor that does no validation (null check + array length check).
An unsafe method returning something like
return new Guid(
((int)(bytes+10)),
((short)(bytes+14)),
((short)(bytes+8)),
*(bytes+9),
*(bytes+6),
*(bytes+7),
*(bytes+4),
*(bytes+5),
*(bytes+0),
*(bytes+1),
*(bytes+2),
*(bytes+3))
Would probably be faster - thought I'm not sure if my endianness is correct. Otherwise you'd have to do that casting yourself as it (bytes+13) << 0x18 | ((bytes+12)) << 0x10 | ((bytes+11)) << 0x8 | ((bytes+10))
but it would still probably be just a bit faster
In TransformToValueForEsentSorting you could rearrange the values in the array that ToByteArray returns rather than creating a new array.
Bags not writing the code.
Run it on Linux. They say it's faster.
Correct spelling is a good way to increase code speed.
TransfromToGuidWithProperSorting
According to reflector the most optimal ctor is public Guid(int a, short b, short c, byte d, byte e, byte f, byte g, byte h, byte i, byte j, byte k) btw. I cannot believe that it takes 0.08us because that would be only about 12k times a second. I would expect a 100 times that easily.
@tobi How did you calculate that?
1000 ms / 0.000008 = 125'000'000
@Frank,
I think you have an extra 0 in there. It should be 8x10^-5 not 8x10^-6.
@tobi,
Even still, that makes it 12 million times per second, not 12 thousand.
@Harry That totally stole my thunder :)
Indeed, this code
public static Guid TransfromToGuidWithProperSorting(this byte[] array)
runs roughly 40-50% faster on my machine in comparison.
I know you aren't the most avid SO user, but putting this up there as performance code golf might get you better responses than here.
Harry, "Even still, that makes it 12 million times per second, not 12 thousand." I don't think this is true. 0.001 would be 1k a second, 0.0001 = 10k/second. then mul by 8/10.
You probably shouldnt be doing what you are doing, but instead create your own Guid type implementation that knows how to compare (sort properly)
Messing with the Guids internal structure, will make it difficult to read/understand the code as you would have to know about what type of Guid you are dealing with, if it has been changed and how it structured.
Also you dont need the conversion at all, which is even better.
Use Reflector to look at how the SqlGuid is implemented, which is used to compare/sort Comb.Guids correctly (by the last 6 bytes).
http://msdn.microsoft.com/en-us/library/ms254976(VS.80).aspx
Martin :)
@tobi
Ayende said 0.00008 MILLISECONDS, not 0.00008 seconds. So adding three orders of magnitude above 12,000 you get...
Ah you are right! Well, what an important discussion ;-)
Hmm I recognise the article code ;) Interesting to see the variations.
Comment preview