July 2006 - Posts

More on string reversal!

Cross-posted from SQLBlog! - http://www.sqlblog.com


In the last installment, I showed a potentially fastest method using Array.Reverse.

After finding and fixing a bug in method #3 posted in my last installment (it is, in fact, quite a bit faster than method #1 when you don't have a big huge bug in the code ) creating a new method, and hearing from Mladenp about a method he came up with, I decided that I should post another round of results.  So, here are the five methods I'm now testing:

        public static string Reverse1(string s)
        {
            StringBuilder sb = new System.Text.StringBuilder(s.Length);
            int i = s.Length;

            while (i-- > 0)
            {
                sb.Append(s[i]);
            }

            return sb.ToString();
        }

        public static string Reverse2(string s)
        {
            char[] rev = s.ToCharArray();
            Array.Reverse(rev);
            return (new string(rev));
        }

        public static string Reverse3(string s)
        {
            char[] charArray = s.ToCharArray();

            int i = charArray.Length;

            StringBuilder sb = new System.Text.StringBuilder(i);           

            while (i-- > 0)
            {
                sb.Append(charArray[i]);
            }

             return sb.ToString();
        }

        public static string Reverse4(string s)
        {
            char[] charArray = s.ToCharArray();

            int i = charArray.Length;
            int j = i-1;

            string[] outStr = new string[i];

            while (i-- > 0)
            {
                outStr[j - i] = charArray[i].ToString();
            }

            return String.Join("", outStr);
        }

        public static string Reverse5(string s)
        {
            char[] charArray = s.ToCharArray();
            int len = s.Length - 1;

            for (int i = 0; i < len; i++, len--)
            {
                charArray[i] ^= charArray[len];
                charArray[len] ^= charArray[i];
                charArray[i] ^= charArray[len];
            }

            return new string(charArray);
        }


Results (10000 iterations, 26-character string):

Reverse1: 106.767 ms
Reverse2: 12.752 ms
Reverse3: 61.902 ms
Reverse4: 87.963 ms
Reverse5: 12.15 ms

Winner, by a very small margin: Mladenp's XOR method!

Anyone else want to weigh in?  Submissions are open!

Reversing a string in .NET

Cross-posted from SQLBlog! - http://www.sqlblog.com


Over in the Simple-Talk forums, there is a good thread going about how best to reverse a string in .NET, since no string reverse method is included in the BCL.

A few suggestions were made, and someone implied that they were too complex and that simplicity is the most important factor.  Personally, I wonder -- does complexity really matter in this case?  I would expect that you'd program this kind of thing exactly once, put it into a utility class somewhere, and never worry about the implementation again.  Given that assumption, it becomes more of a performance question for me.

To that end, I've run a few tests.  I created three methods -- the first is a method using StringBuilder, as suggested by one of the respondants in the thread who felt it was the simplest method of achieving tho goal.  The second uses Array.Reverse, and is perhaps slightly more obscure.  The third method is a modification of the first, in which the main loop iterates over an array of chars instead of the string, which I had a hunch would be faster (alas, tests show that I was not correct in my assumption).  Following are the methods:

        public static string Reverse1(string s)
        {
            StringBuilder sb = new System.Text.StringBuilder(s.Length);
            int i = s.Length;

            while (i-- > 0)
            {
                sb.Append(s[i]);
            }

            return sb.ToString();
        }

        public static string Reverse2(string s)
        {
            char[] rev = s.ToCharArray();
            Array.Reverse(rev);
            return (new string(rev));
        }

        public static string Reverse3(string s)
        {
            char[] charArray = s.ToCharArray();

            int i = charArray.Length;

            StringBuilder sb = new System.Text.StringBuilder(i);           

            while (i-- > 0)
            {
                sb.Append(s[i]);
            }

            return sb.ToString();
        }


I turned on Visual Studio's profiler to collect timings and ran these methods in a loop.  First test was reversing 26 characters (a-z), which I ran in a loop 10,000 times for each method.  Results:

Reverse1: 506.775 ms
Reverse2: 58.327 ms
Reverse3: 522.484 ms

The second test was reversing 2080 characters (a-z repeated 80 times).  I was only able to run this test in the loop 2500 times, as my workstation is currently very low on disk space and the VS profiler's output takes up a lot of room.  Results:

Reverse1: 2060.424 ms
Reverse2: 117.874 ms
Reverse3: 2368.861 ms

Results are total time spent in each function and its children over the course of all iterations.

So for me, the Array.Reverse method is what I would use... Anyone out there have a better version to share?


This blog is en route elsewhere...

Like several others on this site, I've decided to pick up and move.

I'll be mirroring back here for the time being (perhaps the next three months), but after that I will turn off this feed and say goodbye to SQLJunkies.  Given the annoying technical problems that never get fixed, horrible banner ads covering all of our blogs, not to mention the general mismanagement of this site as a whole, it's just not worth it for me to continue blogging here.

Please join me at my new home, SQLBlog.com!  I have a lot of interesting content lined up for the coming months, and I look forward to building a new and better blog site over there.  See you all there, and thank you for reading my content here for the past year and a half!