朴素反转
朴素解法,倒序遍历,字符串拼接,字符串性能低下,在长度已知的前提可以使用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();
结语
写这些代码到底有什么意义?性能到底如何?好了,那么问题来了