zoukankan      html  css  js  c++  java
  • 高效的忽略大小写的字符串替换(Replace)函数(多种方法比较)

    关键字:.NET,String,Replace,字符串,替换,忽略大小写,VB,Regexp,Regular Expression,正则表达式,Reflector,Run-Time,运行时,StringBuilder,效率
    创建时间:2005/06/30 15:40
    最后修改:2005/06/30 20:52
    作者:灵感之源

    前言

    在开发中,我们要常和各种不同类型的信息打交道,无论是数据库中的信息还是网络的、甚至财务的数据,最终都可以ToString()为字符串(这个说法有点牵强)。所以我们日常常要和字符串打交道。


    主题

    在.NET中,不调用C++/CLI,进行字符串替换有好几种方法:

    1、最常用的,就是String实例.Replace(),但这个不能忽略大小写。

    2、System.Text.Regex(Regular Expression正则表达式),大家都估计到它的效率不高,虽然它支持忽略大小写。

    3、String.SubString()循环,查找要替换的子字符串的位置,截取,然后字符串相加,大家也估计到,数量少(在codeproject.com上曾有文章讨论过和StringBuilder的临届值是600次)的情况下会比StringBuilder快。

    4、跟3一样,唯一区别就是字符累加用StringBuilder,数量少的情况下比字符累加要慢,但过了临届值就要快。

    5、引用Microsoft VisualBasic RunTime(Microsoft.VisualBasic.DLL),里面有一个Strings.Replace,效率非常高,其原理就是:Split()再Join(),其中Split支持忽略大小写的秘诀就是调用了System.Globalization.CultureInfo,也就是所谓的国际化,其实要实现字符串的替换代码量不多,但要兼容各种语言(非编程语言,是交流语言),那就得多花几倍的代码了。

    6、不想用VB运行库的朋友,可以用Reflector配合Denis Bauer's Reflector.FileDisassembler把Microsoft.VisualBasic.DLL中的Strings的Replace和相关函数抽取出来(C#),然后修补一下就可以单独使用了(我这明显是吃饱了撑着,VB专家装配脑袋指出我这是浪费时间,因为本身Microsoft VisualBasic运行库就包括在.NET Framework中)。


    实战


    以下是测试代码:
            static void Main(string[] args)
            
    {
                
    string segment = "中华aBc共和国";
                
    string source;
                
    string pattern = "abc";
                
    string destination = "人民";
                
    string result = "";
                
    const long count = 1000;
                StringBuilder pressure 
    = new StringBuilder();
                HiPerfTimer time;

                
    for (int i = 0; i < count; i++)
                
    {
                    pressure.Append(segment);
                }

                source 
    = pressure.ToString();
        
                
    //regexp
                time = new HiPerfTimer();
                time.Start();
                
    for (int i = 0; i < count; i++)
                
    {
                    result 
    = Regex.Replace(source, pattern, destination, RegexOptions.IgnoreCase);
                }

                time.Stop();

                Console.WriteLine(
    "regexp    =" + time.Duration + ":");


                
    //vb
                time = new HiPerfTimer();
                time.Start();
                
    for (int i = 0; i < count; i++)
                
    {
                    result 
    = Strings.Replace(source, pattern, destination, 1-1, CompareMethod.Text);
                }

                time.Stop();

                Console.WriteLine(
    "vb        =" + time.Duration + ":");


                
    //vbReplace
                time = new HiPerfTimer();
                time.Start();
                
    for (int i = 0; i < count; i++)
                
    {
                    result 
    = VBString.Replace(source, pattern, destination, 1-1, StringCompareMethod.Text);
                }

                time.Stop();

                Console.WriteLine(
    "vbReplace =" + time.Duration + ":" + result);


                
    //substring
                time = new HiPerfTimer();
                time.Start();
                
    for (int i = 0; i < count; i++)
                
    {
                    result 
    = StringHelper.ReplaceText(source, pattern, destination, StringHelper.CompareMethods.Text);
                }

                time.Stop();

                Console.WriteLine(
    "substring =" + time.Duration + ":");


                
    //substring with stringbuilder
                time = new HiPerfTimer();
                time.Start();
                
    for (int i = 0; i < count; i++)
                
    {
                    result 
    = StringHelper.ReplaceTextB(source, pattern, destination, StringHelper.CompareMethods.Text);
                }

                time.Stop();

                Console.WriteLine(
    "substringB=" + time.Duration + ":");


                Console.ReadLine();
            }


    说明

    这个代码演示了上述几种方法:要把字符串"中华aBc共和国"中的"abc"替换为"人民",注意:源子字符串是"aBc",要替换的是"abc",这里目的是要测试不区分大小写。

    为了测试效率,我特意先把测试字符串累加1000次,然后循环测试1000次。


    结果

    以下是测试结果:
    regexp      =1.38308285017339 //这是正则表达式,第3快;
    vb            =0.525978828344589 //这是引用Microsoft VisualBasic RunTime的,次快;
    vbReplace=0.522997341400086 //这就是用reflector改为C#的,最快;
    substring  =21.8573638474698 //这是string.substring +,最慢
    substringB=14.6346693500287 //这是string.substring StringBuilder,次慢,这里凸现了StringBuilder的速度;

    这里仅仅是多次测试中的一次,我没有弄平均,大概数字吧,到底是vb快还是reflector的c#快,差不多...

    是否应该使用Microsoft VisualBasic RunTime就见仁见智了。


    后话
    不过装配脑袋指出,“可以使用C++的std::basic_string<T>::replace”实现高效的字符串替换。


    资源下载
    限于篇幅,具体的代码,请点击这里下载。


    关联
    鸟食轩(birdshome)发表了他的解决方案,进行了有益的讨论:忽略字符串大小写替换的更高效实现

    外部发表
    我在codeproject上发表了这篇文章,结合了birdshome的文章:Fastest C# Case Insenstive String Replace
  • 相关阅读:
    内存泄漏 Memory Leaks 内存优化 MD
    Handler Thread 内部类引起内存泄露分析
    为什么不取消注册BroadcastReceiver会导致内存泄漏
    WebChromeClient 简介 API 案例
    WebViewClient 简介 API 案例
    java.net.URI 简介 文档 API
    android.net.Uri 简介 API
    RV 多样式 MultiType 聊天界面 消息类型 MD
    JS函数声明与定义,作用域,函数声明与表达式的区别
    CSS中table tr:nth-child(even)改变tr背景颜色: IE7,8无效
  • 原文地址:https://www.cnblogs.com/unruledboy/p/StringReplace.html
Copyright © 2011-2022 走看看