从字符串中查找字符出现次数的方法和性能再比

    原文是Ninputer所发,名叫“从字符串中查找字符出现次数的方法和性能对比”。

    他在里面用了三种办法来查找'A'在"SADTHDGSAFSDGTGHRDGSADFADDRHDFSGASDAA"中的出现次数,可是我的测试结果的差别完全没有他的那么明显,三种方法最多也就相差2.5-2.7倍。也就是说遍历法和分割法只有不到3倍的效率差别,下面是上面那个字符串被三种方法测试1M遍的结果:
    1、遍历统计长度: 613ms
    2、替换后比较长度: 1,064ms
    3、断开字符串后计数: 1,611ms

    讨论后大家觉得一般情况下使用第二种方法是最经济的,因为少的代码会使程序的正确性得到提高,且在效率的损失也是可以接受的情况下。

    这里可以对第二个方法有个优化,把:
    c1 = str.Length - str.Replace("A", "").Length;
    改成:
    StringBuilder strb = new StringBuilder(str);
    c1 = str.Length - strb.Replace("A", "").Length;

    这次运行1M次的测试结果是:1,395ms,基本就是遍历法的两倍,而且我们还可以发现,这个方法的时间有1/3都是消耗在第一句建立StringBuilder上面,在这个的测试中它花费了578ms。

    结下来是讨论了一下把str的采样空间变大,我把str复制了20份,长度达到了740个字节,这下测试1M次的结果如下:
    1、遍历统计长度: 11,583ms
    2、替换后比较长度: 17,454ms
    3、断开字符串后计数: 26,953ms
    4、改进后的替换法比较: 18,625ms(其中12,518的时间消耗在StringBuilder的建立上)。

    可以看出StringBuilder里的native方法是效率极高的,再刨去其创建时的消耗后甚至高过了遍历法emdgust.gif,可是StringBuilder的创建也是很费时间的,真是难以取舍呀。  

    测试环境:P4 2.4 512M WinXp .NET Framework 1.1.
    附测试代码:

ContractedBlock.gif ExpandedBlockStart.gif test code #region test code
InBlock.gif
using System;
InBlock.gif
using System.Text;
InBlock.gif
InBlock.gif
namespace CharCount
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif    
/**//// <summary>
InBlock.gif    
/// Summary description for CharCount.
ExpandedSubBlockEnd.gif    
/// </summary>

InBlock.gif    class CharCount
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
InBlock.gif        
/// The main entry point for the application.
ExpandedSubBlockEnd.gif        
/// </summary>

InBlock.gif        [STAThread]
InBlock.gif        
static void Main(string[] args)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
string str = "SADTHDGSAFSDGTGHRDGSADFADDRHDFSGASDAA";
InBlock.gif
InBlock.gif            
long t;
InBlock.gif            
int len;
InBlock.gif            
string strTemp = string.Empty;
InBlock.gif            
for ( int i=0 ; i < 20 ; i++ )
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                strTemp 
+= str;
ExpandedSubBlockEnd.gif            }

InBlock.gif            str 
= strTemp;
InBlock.gif            GC.Collect();
InBlock.gif
InBlock.gif            DateTime dtBegin 
= DateTime.Now;
InBlock.gif            
for ( int j=0 ; j < 100000 ; j++ )
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif                
/**//*len = 0;
InBlock.gif                for ( int k=0 ; k < str.Length ; k++ )
InBlock.gif                {
InBlock.gif                    if ( str[k] == 'A')
InBlock.gif                    {
InBlock.gif                        len++;
InBlock.gif                    }
ExpandedSubBlockEnd.gif                }
*/

InBlock.gif                
//len = str.Length - str.Replace("A", "").Length;
InBlock.gif                
//len = str.Split(new char [] {'A'}).Length;
InBlock.gif
                StringBuilder strb = new StringBuilder(str);
InBlock.gif                len 
= strb.Length - strb.Replace("A""").Length;
ExpandedSubBlockEnd.gif            }

InBlock.gif            t 
= (long)(DateTime.Now - dtBegin).TotalMilliseconds;
InBlock.gif            System.Console.WriteLine(str.Length 
+ "" + t);
InBlock.gif            System.Console.Read();
ExpandedSubBlockEnd.gif        }

ExpandedSubBlockEnd.gif    }

ExpandedSubBlockEnd.gif}

ExpandedBlockEnd.gif
#endregion
None.gif

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值