朴素反轉
朴素解法,倒序遍歷,字符串拼接,字符串性能低下,在長度已知的前提可以使用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();
結語
寫這些代碼到底有什么意義?性能到底如何?好了,那么問題來了
