zoukankan      html  css  js  c++  java
  • 几种字符串反转方法效率比较

    面是实现字符串反转的四种方法:
                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] 
    = '
     
  • 相关阅读:
    转载:史上最全|阿里那些牛逼带闪电的开源工具,你知道几个?
    互怼、IPO、雷潮、寒冬,2018 互联网圈的那些事儿
    微信迎来又一次重大改版 7.0 版本
    公众号文章目录
    聊几个与赚钱相关的小事情
    使用docker Registry快速搭建私有镜像仓库
    开源组件ELK日志系统配置与管理
    Mysql MHA高可用集群架构
    强大的开源企业级数据监控利器Lepus安装与配置管理
    关于下载gitbash客户端
  • 原文地址:https://www.cnblogs.com/encounter/p/2188826.html
Copyright © 2011-2022 走看看