Geeks With Blogs
Greg Young Greg.ToString()

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

 

Posted on Thursday, April 27, 2006 1:04 AM Under the covers | Back to top


Comments on this post: More fun a'la Alois (evil)

# re: More fun a'la Alois (evil)
Requesting Gravatar...
This is really evil. But perhaps is this technique good in another scenario.

Yours,
Alois Kraus
Left by Alois Kraus on Apr 27, 2006 2:55 PM

# re: More fun a'la Alois (evil)
Requesting 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
Left by Greg Young on Apr 27, 2006 4:39 PM

Your comment:
 (will show your gravatar)
 


Copyright © Greg Young | Powered by: GeeksWithBlogs.net | Join free