|
下面是實(shí)現(xiàn)字符串反轉(zhuǎn)的四種方法:
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()中對(duì)char[]進(jìn)行了兩次賦值(ToCharArray()和Array.Revease),所以我有想到了Revease2和Revease3()兩種方法,下面是對(duì)這四種方法進(jìn)行簡(jiǎn)單性能測(cè)試的代碼: static void Main(string[] args)![]() ...{ string testString = "測(cè)試字符串反轉(zhuǎn)測(cè)試字符串反轉(zhuǎn)測(cè)試字符串反轉(zhuǎn)測(cè)試字符串反轉(zhuǎn)測(cè)試字符串反轉(zhuǎn)測(cè)試字符串反轉(zhuǎn)測(cè)試字符串反轉(zhuǎn)測(cè)試字符串反轉(zhuǎn)測(cè)試字符串反轉(zhuǎn)測(cè)試字符串反轉(zhuǎn)測(cè)試字符串反轉(zhuǎn)測(cè)試字符串反轉(zhuǎn)測(cè)試字符串反轉(zhuǎn)測(cè)試字符串反轉(zhuǎn)測(cè)試字符串反轉(zhuǎn)測(cè)試字符串反轉(zhuǎn)測(cè)試字符串反轉(zhuǎn)測(cè)試字符串反轉(zhuǎn)測(cè)試字符串反轉(zhuǎn)測(cè)試字符串反轉(zhuǎn)測(cè)試字符串反轉(zhuǎn)測(cè)試字符串反轉(zhuǎn)測(cè)試字符串反轉(zhuǎn)測(cè)試字符串反轉(zhuǎn)測(cè)試字符串反轉(zhuǎn)測(cè)試字符串反轉(zhuǎn)測(cè)試字符串反轉(zhuǎn)測(cè)試字符串反轉(zhuǎn)測(cè)試字符串反轉(zhuǎn)測(cè)試字符串反轉(zhuǎn)測(cè)試字符串反轉(zhuǎn)測(cè)試字符串反轉(zhuǎn)"; 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(); }測(cè)試結(jié)果是Revease1()代碼最簡(jiǎn)潔,運(yùn)行速度也最快,Revease21()和Revease22()其次,Revease3()最慢??梢?jiàn).net framework中實(shí)現(xiàn)的ToCharArray()和Array.Revease()效率還是蠻高的^_^ 但還有個(gè)奇怪的問(wèn)題,就是Debug版本中的Revease1()和Revease21()運(yùn)行起來(lái)要比Release版本中的要快,而Revease22()和Revease3()就比較正常。按說(shuō)Release時(shí)做了更多的優(yōu)化工作,運(yùn)行起來(lái)更快才對(duì),迷惑ing...,下面是測(cè)試結(jié)果: Debug: 1 : 00:00:03.4375000
Release: 1 : 00:00:05.7812500
附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] = ‘ |
|
|
來(lái)自: 鳳舞天煌 > 《JAVA技術(shù)》