朴素反轉
朴素解法,倒序遍歷,字符串拼接,字符串性能低下,在長度已知的前提可以使用char數組代替
public static string NaiveReverse(string text) { string reverse = string.Empty; for (int i = text.Length - 1; i >= 0; i--) { reverse += text[i]; } return reverse; }
StringBuilder拼接
進一步改進,使用StringBuilder進行拼接字符串
public static string SBReverse(string text) { StringBuilder builder = new StringBuilder(text.Length); for (int i = text.Length - 1; i >= 0; i--) { builder.Append(text[i]); } return builder.ToString(); }
二分反轉
遍歷次數降低到一半,效果如何?
public static string BinaryReverse(string text) { char[] charArray = text.ToCharArray(); int len = text.Length - 1; for (int i = 0; i < len; i++, len--) { char tmp = charArray[i]; charArray[i] = charArray[len]; charArray[len] = tmp; } return new string(charArray); }
指針操作
咦?字符串居然可變?
public static unsafe string UnsafeReverse(string text) { fixed (char* pText = text) { char* pStart = pText; char* pEnd = pText + text.Length - 1; for (int i = text.Length / 2; i >= 0; i--) { char temp = *pStart; *pStart++ = *pEnd; *pEnd-- = temp; } return text; } }
數組反轉
最容易理解的方式,往往是最高效的,為啥這么高效?
public static string ArrayReverse(string text) { char[] charArray = text.ToCharArray(); Array.Reverse(charArray); return new string(charArray); }
XOR操作
是不是很有逼格?其實對於理解位操作還是有點幫助,至於性能嘛。。。
public static string XorReverse(string text) { char[] charArray = text.ToCharArray(); int len = text.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); }
FCL實現
升級到.NET3.5了嗎?OK,最少的代碼實現,可是性能嘛,額
public static string EnumReverse(string text) { char[] reverse = text.Reverse().ToArray(); return new string(reverse); }
測試
Stopwatch watcher = new Stopwatch(); // 字符串規模 int[] sizes = new[] { 10, 100, 1000, 10000 }; // 反轉方法列表 var ReverseMethods = new Func<string, string>[] { NaiveReverse, SBReverse, BinaryReverse, UnsafeReverse, ArrayReverse, XorReverse, EnumReverse }; for (int i = 0; i < sizes.Length; i++) { string text = new string('X', sizes[i]); Console.WriteLine("For Size: {0}", sizes[i]); for (int j = 0; j < ReverseMethods.Length; j++) { var invoker = ReverseMethods[j]; watcher.Restart(); invoker(text); watcher.Stop(); Console.WriteLine("{0} Ticks: {1}", invoker.Method.Name, watcher.ElapsedTicks); } Console.WriteLine(); } Console.ReadLine();
結語
寫這些代碼到底有什么意義?性能到底如何?好了,那么問題來了