Blog Stats
  • Posts - 99
  • Articles - 5
  • Comments - 30
  • Trackbacks - 111

 

More fun a'la Alois (evil)

A wee bit faster for http://geekswithblogs.net/akraus1/archive/2006/04/23/76146.aspx

ok so Jeffery had gotten it down to 0.26 seconds on my machine ... http://blogs.extremeoptimization.com/jeffrey/archive/2006/04/26/13824.aspx did some really slick math to make things a little bit quicker.

but lets have a little fun with this ..

I feel like this should have a disclaimer on it. I will show why after. I have taken Jefferey's modified code and applied this dubious change to it ...

THIS IS HORRIBLY WRONG DO NOT DO THIS .. EVER

but first ... the results :)

FF6, FF7 00:00:00.2792670, 00:00:00.1729169
FF6, FF7 00:00:00.2526043, 00:00:00.1714421
FF6, FF7 00:00:00.2591204, 00:00:00.1735528
FF6, FF7 00:00:00.2639455, 00:00:00.1720244
FF6, FF7 00:00:00.2612275, 00:00:00.1735536
FF6, FF7 00:00:00.2594508, 00:00:00.1721212
FF6, FF7 00:00:00.2576327, 00:00:00.1741244
FF6, FF7 00:00:00.2599935, 00:00:00.1716131
FF6, FF7 00:00:00.2594535, 00:00:00.1719833
FF6, FF7 00:00:00.2582957, 00:00:00.1724466
FF6, FF7 00:00:00.2584063, 00:00:00.1769534
FF6, FF7 00:00:00.2614212, 00:00:00.1722529
FF6, FF7 00:00:00.2580468, 00:00:00.1742682
FF6, FF7 00:00:00.2557166, 00:00:00.1729530
FF6, FF7 00:00:00.2538459, 00:00:00.1703076
FF6, FF7 00:00:00.2549899, 00:00:00.1714912
FF6, FF7 00:00:00.2558009, 00:00:00.1717028

not too shabby ... unfortunately the methodology used to get these results is umm bad.

Strings are immutable right? Not always ...

Paragraph 10 (Page 335, Line 49)
1 Modifying objects of managed type through fixed pointers can result in undefined behavior. Note: For example, because strings are immutable, it is the programmer's responsibility to ensure that the characters referenced by a pointer to a fixed string are not modified. end note

Well lets pretend strings are NOT immutable! Note that Init() would generally be a static contructor not a seperate function.

        static char* p = null;
        static string foo = "  :  :  .   ";
        private static void Init()
        {
           
            GCHandle test = GCHandle.Alloc(foo, GCHandleType.Pinned);
            p = (char *)test.AddrOfPinnedObject().ToInt32();
        }

        private unsafe static string FormatFast7(DateTime time)
        {
                long ticks = time.Ticks;
                char* a = p;
                int ms = (int)((ticks / 10000) % 86400000);
                int hour = (int)(Math.BigMul(ms >> 7, 9773437) >> 38);
                ms -= 3600000 * hour;
                int minute = (int)((Math.BigMul(ms >> 5, 2290650)) >> 32);
                ms -= 60000 * minute;
                int second = ((ms >> 3) * 67109) >> 23;
                ms -= 1000 * second;

                int temp = (hour * 13) >> 7;
                *a = (char)(temp + '0');
                a++;
                *a = (char)(hour - 10 * temp + '0');
                a += 2;

                temp = (minute * 13) >> 7;
                *a = (char)(temp + '0');
                a++;
                *a = (char)(minute - 10 * temp + '0');
                a += 2;

                temp = (second * 13) >> 7;
                *a = (char)(temp + '0');
                a++;
                *a = (char)(second - 10 * temp + '0');
                a += 2;

                temp = (ms * 41) >> 12;
                *a = (char)(temp + '0');
                a++;
                ms -= 100 * temp;
                temp = (ms * 205) >> 11;
                *a = (char)(temp + '0');
                ms -= 10 * temp;
                a++;
                *a = (char)(ms - 10 * temp + '0');
                return foo;
        }

Now I feel it very important to say again THIS IS BAD (but it is VERY fast). Why is it bad?

In the original example we used a static char array which made the function non-reentrant ... this is similar but worse ... take the following code ..

            DateTime start = DateTime.Now;
            string string1 = FormatFast7(start);
            Console.WriteLine("string 1=" + string1);
            start = DateTime.Parse("1/1/2006 13:01:23");
            string string2 = FormatFast7(start);
            Console.WriteLine("string2 = " + string2);
            Console.WriteLine("string1 = " + string1);

Here is the output ... scary huh?

string 1=04:00:27.45
string2 = 13:01:23.000
string1 = 13:01:23.000

But it was the FASTEST format function not the fastest format function that was also not horribly evil :) I think Jeff gets the fastest function award though :)

 


Feedback

# re: More fun a'la Alois (evil)

Gravatar This is really evil. But perhaps is this technique good in another scenario.

Yours,
Alois Kraus
4/27/2006 2:55 PM | Alois Kraus

# re: More fun a'la Alois (evil)

Gravatar No, I don't ever think its good.

But applying the static constructor and pinning the char array adds a bit on my machine too, so thats something you might want to add to the fastest function 4/27/2006 4:39 PM | Greg Young

Post a comment





 

Please add 3 and 4 and type the answer here:

 

 

Copyright © Greg Young