下面是实现字符串反转的四种方法:
static
string
Reverse1(
string
original)

...
{
char[] arr = original.ToCharArray();
Array.Reverse(arr);
return new string(arr);
}

static
string
Revease21(
string
original)

...
{
int length = original.Length;
char[] arr = new char[length];
for (int i = 0; i < (length & (~3)); i += 4)

...{
arr[i] = original[length - i - 1];
arr[i+1] = original[length - i - 2];
arr[i+2] = original[length - i - 3];
arr[i+3] = original[length - i - 4];
}
for (int i = length & (~3); i < length; i++)

...{
arr[i] = original[length - i - 1];
}
return new string(arr);
}

static
string
Revease22(
string
original)

...
{
int length = original.Length;
char[] arr = new char[length];
for (int i = 0; i < length; i++)

...{
arr[i] = original[length - i - 1];
}
return new string(arr);
}

static
string
Revease3(
string
original)

...
{
int length = original.Length;
StringBuilder sb = new StringBuilder(length);
for (int i = length-1; i >= 0; i--)
sb.Append(original[i]);
return sb.ToString();
}
Revease1()中对char[]进行了两次赋值(ToCharArray()和Array.Revease),所以我有想到了Revease2和Revease3()两种方法,下面是对这四种方法进行简单性能测试的代码:
static
void
Main(
string
[] args)

...
{
string testString = "测试字符串反转测试字符串反转测试字符串反转测试字符串反转测试字符串反转测试字符串反转测试字符串反转测试字符串反转测试字符串反转测试字符串反转测试字符串反转测试字符串反转测试字符串反转测试字符串反转测试字符串反转测试字符串反转测试字符串反转测试字符串反转测试字符串反转测试字符串反转测试字符串反转测试字符串反转测试字符串反转测试字符串反转测试字符串反转测试字符串反转测试字符串反转测试字符串反转测试字符串反转测试字符串反转测试字符串反转测试字符串反转";
DateTime start = DateTime.Now;
for (int i = 0; i < 3000000; i++)

...{
string s = Reverse1(testString);
}
DateTime end = DateTime.Now;
Console.WriteLine("1 : "+(end - start));

start = DateTime.Now;
for (int i = 0; i < 3000000; i++)

...{
string s = Revease21(testString);
}
end = DateTime.Now;
Console.WriteLine("21: " + (end - start));

start = DateTime.Now;
for (int i = 0; i < 3000000; i++)

...{
string s = Revease22(testString);
}
end = DateTime.Now;
Console.WriteLine("22: " + (end - start));

start = DateTime.Now;
for (int i = 0; i < 3000000; i++)

...{
string s = Revease3(testString);
}
end = DateTime.Now;
Console.WriteLine("3 : " + (end - start));

Console.ReadLine();
}
测试结果是Revease1()代码最简洁,运行速度也最快,Revease21()和Revease22()其次,Revease3()最慢。可见.net framework中实现的ToCharArray()和Array.Revease()效率还是蛮高的^_^
但还有个奇怪的问题,就是Debug版本中的Revease1()和Revease21()运行起来要比Release版本中的要快,而Revease22()和Revease3()就比较正常。按说Release时做了更多的优化工作,运行起来更快才对,迷惑ing...,下面是测试结果:
Debug:
1 : 00:00:03.4375000
21: 00:00:06.1250000
22: 00:00:09.9687500
3 : 00:01:05.5468750
Release:
1 : 00:00:05.7812500
21: 00:00:07.4218750
22: 00:00:08.2500000
3 : 00:00:50.3593750
附1:Array.Revease()方法的源码(由Reflector.exe反汇编得到):
[ReliabilityContract(Consistency.MayCorruptInstance, Cer.MayFail)]
public
static
void
Reverse(Array array)

...
{
if (array == null)

...{
throw new ArgumentNullException("array");
}
Array.Reverse(array, array.GetLowerBound(0), array.Length);
}

[ReliabilityContract(Consistency.MayCorruptInstance, Cer.MayFail)]
public
static
void
Reverse(Array array,
int
index,
int
length)

...
{
int num1;
int num2;
if (array == null)

...{
throw new ArgumentNullException("array");
}
if ((index < array.GetLowerBound(0)) || (length < 0))

...{
throw new ArgumentOutOfRangeException((index < 0) ? "index" : "length", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
}
if ((array.Length - (index - array.GetLowerBound(0))) < length)

...{
throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
}
if (array.Rank != 1)

...{
throw new RankException(Environment.GetResourceString("Rank_MultiDimNotSupported"));
}
if (!Array.TrySZReverse(array, index, length))

...{
num1 = index;
num2 = (index + length) - 1;
object[] objArray1 = array as object[];
if (objArray1 == null)

...{
goto Label_00DE;
}
while (num1 < num2)

...{
object obj1 = objArray1[num1];
objArray1[num1] = objArray1[num2];
objArray1[num2] = obj1;
num1++;
num2--;
}
}
return;
Label_00DE:
if (num1 >= num2)

...{
return;
}
object obj2 = array.GetValue(num1);
array.SetValue(array.GetValue(num2), num1);
array.SetValue(obj2, num2);
num1++;
num2--;
goto Label_00DE;
}
附2:StringBuilder.Append()方法的源码(由Reflector.exe反汇编得到):
public
StringBuilder Append(
string
value)

...
{
if (value != null)

...{
string text1 = this.m_StringValue;
IntPtr ptr1 = Thread.InternalGetCurrentThread();
if (this.m_currentThread != ptr1)

...{
text1 = string.GetStringForStringBuilder(text1, text1.Capacity);
}
int num1 = text1.Length;
int num2 = num1 + value.Length;
if (this.NeedsAllocation(text1, num2))

...{
string text2 = this.GetNewString(text1, num2);
text2.AppendInPlace(value, num1);
this.ReplaceString(ptr1, text2);
}
else

...{
text1.AppendInPlace(value, num1);
this.ReplaceString(ptr1, text1);
}
}
return this;
}

private
bool
NeedsAllocation(
string
currentString,
int
requiredLength)

...
{
return (currentString.ArrayLength <= requiredLength);
}

internal
unsafe
void
AppendInPlace(
string
value,
int
currentLength)

...
{
int num1 = value.Length;
int num2 = currentLength + num1;
fixed (char* chRef1 = &this.m_firstChar)

...{
fixed (char* chRef2 = &value.m_firstChar)

...{
string.wstrcpy(chRef1 + currentLength, chRef2, num1);
}
chRef1[num2] = '