Ayende @ Rahien

Hi!
My name is Oren Eini
Founder of Hibernating Rhinos LTD and RavenDB.
You can reach me by phone or email:

ayende@ayende.com

+972 52-548-6969

, @ Q c

Posts: 18 | Comments: 87

filter by tags archive

Can you make this code run any faster?

time to read 3 min | 597 words

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

Steve

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).

configurator

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

James Newton-King

In TransformToValueForEsentSorting you could rearrange the values in the array that ToByteArray returns rather than creating a new array.

Bags not writing the code.

Ken Egozi

Run it on Linux. They say it's faster.

Ed James

Correct spelling is a good way to increase code speed.

TransfromToGuidWithProperSorting

tobi

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.

Frank Quednau

@tobi How did you calculate that?

1000 ms / 0.000008 = 125'000'000

Harry Steinhilber

@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.

Frank Quednau

@Harry That totally stole my thunder :)

Indeed, this code

public static Guid TransfromToGuidWithProperSorting(this byte[] array)

    {

        return new Guid(

            array[10] + (array[11] << 8) + (array[12] << 16) + (array[13] << 24), 

            (short) (array[14] + (array[15] << 8)), 

            (short) (array[8] + (array[9] << 8)), 

            array[6], array[7], array[4], array[5], array[0], array[1], array[2], array[3]);

    }

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.

tobi

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.

Martin

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 :)

Luc
Luc

@tobi

Ayende said 0.00008 MILLISECONDS, not 0.00008 seconds. So adding three orders of magnitude above 12,000 you get...

tobi

Ah you are right! Well, what an important discussion ;-)

Rik Hemsley

Hmm I recognise the article code ;) Interesting to see the variations.

Comment preview

Comments have been closed on this topic.

FUTURE POSTS

  1. Buffer allocation strategies: A possible solution - about one day from now
  2. Buffer allocation strategies: Explaining the solution - 3 days from now
  3. Buffer allocation strategies: Bad usage patterns - 4 days from now
  4. The useless text book algorithms - 5 days from now
  5. Find the bug: The concurrent memory buster - 6 days from now

There are posts all the way to Sep 11, 2015

RECENT SERIES

  1. Find the bug (5):
    20 Apr 2011 - Why do I get a Null Reference Exception?
  2. Production postmortem (10):
    03 Sep 2015 - The industry at large
  3. What is new in RavenDB 3.5 (7):
    12 Aug 2015 - Monitoring support
  4. Career planning (6):
    24 Jul 2015 - The immortal choices aren't
View all series

Syndication

Main feed Feed Stats
Comments feed   Comments Feed Stats