以下的totalFileCiku为string数组有69558个数据,以head为头的链表有68914个结点。
这段代码为什么会跑得异常的慢呢,大概要19小时。
哪位高手指点一下,问题出在哪里,或者需要怎么优化一下?? /////////////////////////////////////////////////这一块要运行19个钟头!!!!!//////////////////////////////////////
int testHitTime=0;
int testHitTime1=0;
for (current = head.next;current !=null;current = current.next)
{
for(long i = 1; i<=lineNum; i++)
{
//去除空格和TAB符
string[] str2 = System.Text.RegularExpressions.Regex.Split(totalFileCiku[i].Trim(),@"\s+"); Regex   r4   =   new   Regex(@"^[\u4e00-\u9fa5]+$"); 

//判断汉字
if(str2.Length == 2)
{
if   ( r4.IsMatch(str2[0]) )  ci = str2[0];
else if( r4.IsMatch(str2[1]))  ci = str2[1];
else
continue;//若不为汉字这该行忽略。
}
else if(str2.Length == 1)
{
if   ( r4.IsMatch(str2[0]) )  ci = str2[0];
else
continue;//若不为汉字这该行忽略。
}
else
{
continue;//应该不可能到达这里
}
if(current.word == ci)
{ byte[] btr = System.Text.Encoding.Default.GetBytes(totalFileCiku[i]+"\r\n");
memoryOut.Write( btr,0,btr.Length );//将对应的词库行写入临时内存
testHitTime1++;
} }
testHitTime++;
} /////////////////////////////////////////////////这一块要运行19个钟头!!!!!//////////////////////////////////////
附件是整个程序的源代码。

解决方案 »

  1.   

    你跑双重循环里去声明正则,不慢才怪你只判断一个字符是否为汉字,直接比较unicode编码就是了,用正则干嘛代码太长,别的没仔细看
      

  2.   

    19个小时,你算了啊。囧。可以试试StringBuilder。//将对应的词库行写入临时内存
    觉得是这里的问题。
      

  3.   

    哦,不是比较一个字符那你把
    Regex reg = new Regex(@"\s+");
    Regex r4 = new Regex(@"^[\u4e00-\u9fa5]+$"); 
    拿到双重循环外面来声明,看看效率能提升多少
      

  4.   

    我不了解你的需求,只是看着你的代码写的Regex reg = new Regex(@"[\u4e00-\u9fa5]+");
    Match m;
    for (current = head.next; current != null; current = current.next)
    {
        for (long i = 1; i <= lineNum; i++)
        {
            m = reg.Match(totalFileCiku[i]);
            if (m.Success)
            {
                if (current.word == m.Value)
                {
                    byte[] btr = System.Text.Encoding.Default.GetBytes(totalFileCiku[i] + "\r\n");
                    memoryOut.Write(btr, 0, btr.Length);//将对应的词库行写入临时内存
                    testHitTime1++;
                }
            }
            else
            {
                continue;//若不为汉字这该行忽略。
            }
        }
        testHitTime++;
    }
      

  5.   

    switch 貌似是比if else的效率高的
      

  6.   

    不清楚你的需求。memoryOut.Write( btr,0,btr.Length );//将对应的词库行写入临时内存
    testHitTime1++;如果是大量的写,你修改为写文件吧。string[] str2 = System.Text.RegularExpressions.Regex.Split(totalFileCiku[i].Trim(),@"\s+");
    看看能不能在循环之前就处理掉。
      

  7.   

    CSDN这里大家都很热情哦~~ 惊喜。我没有真等19个小时哦。是我用估算出来的,差不多是这个时间。实际上是运行到这里就卡住了。
    先谢谢大家的帮忙。我要完成的任务就是:用以head为头的链表(有68914个结点)里的值去匹totalFileCiku里string数组(有69558个数据)。
    凡是对上了的就将值输出到临时内存中。但是 totalFileCiku里的string数组是用空格分隔的汉字和拼音,
    例如: xyz 李玉蓉 
            关之琳 gzl
    要的只是汉字部分。所以要先处理一下。为什么要输出到临时内存而不是文件里呢。因为出现程序崩溃的时候,临时文件不会被删除,再启动的时候就没办法用了或者会产生垃圾文件。所以选择用临时内存。
      

  8.   

    我试过在启动的时候清理临时文件,常常会出现类似于windows中经常出现的“归文件正在被其它程序使用”之类的问题,没有办法删除,会出现异常。还有如果不用正则应该怎么做匹配呢。
      

  9.   

    LZ最好能把例子说的更详细一些,感觉LZ可以先把totalFileCiku的内容预处理一遍,
    然后用Dictionary做Hash,如果链表里面的文本内容不是巨大的话,应该19秒之内可以处理完。
      

  10.   

              /////////////////////////////////////////////////?一?要?行19个??!!!!!//////////////////////////////////////Dictinary<string,string> nodes=new Dictinary<string,string>();
     for (current = head.next;current !=null;current = current.next)
     {
    nodes.add(current.word,current.word);
     }

    int testHitTime=0;
    int testHitTime1=0;
     Regex   r4   =   new   Regex(@"^[\u4e00-\u9fa5]+$");                 for(long i = 1; i<=lineNum; i++)
                    {
                        //去除空格和TAB符
                        string[] str2 = System.Text.RegularExpressions.Regex.Split(totalFileCiku[i].Trim(),@"\s+");                   
                        
                        //判断?字
                        if(str2.Length == 2)
                        {
                            if   ( r4.IsMatch(str2[0]) )  ci = str2[0];
                            else if( r4.IsMatch(str2[1]))  ci = str2[1];
                            else
                                continue;//若不??字??行忽略。
                        }
                        else if(str2.Length == 1)
                        {
                            if   ( r4.IsMatch(str2[0]) )  ci = str2[0];
                            else
                                continue;//若不??字??行忽略。
                        }
                        else
                        {
                            continue;//??不可能到??里
                        }
                  string s=  nodes.get(ci);
                        if(s!=null)

                        {                            byte[] btr = System.Text.Encoding.Default.GetBytes(totalFileCiku[i]+"\r\n");    
                                memoryOut.Write( btr,0,btr.Length );//将??的??行写入??内存
    testHitTime1++;
                        }                }
                /////////////////////////////////////////////////?一?要?行19个??!!!!!//////////////////////////////////////
      

  11.   

    1 把链表和totalFileCiku分别预处理一下,把需要比对的关键字分别存到两个列表里面并排序。(数据结构随便,怎么方便怎么整) 。
    2 用两个指针遍历两个列表,方法是比较两个指针所指向的值,小的那个指针(假设是升序排列)步进,直到某个指针到达终点。为了方便控制,可以在列表后面追加一个max_value算法如下Int32 i=0,j=0;
    Int32 ll=array1.Length-1,mm=array2.Length-1;
    while(i<ll&&j<mm){
     if(array1[i]==array2[j]){
      //发现匹配的内容,处理(比如说加入某个临时内存什么的)
      i++;j++;
     }else if(array1[i]<array2[j]){
      i++;
     }else{
      j++;
     }
    }
    时间复杂度:
    m=68914,n=69558
    O(m log m)+O(n log n)+m+n
      

  12.   

    先谢谢大家这么热心,学习了。回6楼,lxcnn。把正则表达式给拿到外边确实快了。差不多10几秒就行了。回48楼,litaoye与50楼 angel6709。把链表先hash化应该可以。回55楼,rightyeah。totalFileCiku里的内容没有办法排序,没有可以排序的根据,是一堆杂乱的数据。
    而链表里的数据都是被筛选出来的,对于关键字也是不能排序的。6楼的方案已经能行了,或者加上48、50楼的办法效率更高。