C#:从大文本文件中操作字符串时性能不佳

时间:2014-10-08 12:08:39

标签: c# .net string

我有一个大的txt文件,我必须找到一些记录并将它们重写到其他文件。

我的方法是这样的:

    private ArrayList getRelatingObjects(string[] Ob, string Tab)
    {
        ArrayList rel = new ArrayList();

        foreach (string[] s in SO)
        {
            foreach (string x in s)
            {
               if (x.Length > 0)
               {
                   if (x[0].Equals('W'))
                   {
                       string xTemp = x.Substring(x.IndexOf(',') + 1);
                       xTemp = xTemp.Substring(xTemp.IndexOf(',') + 1);
                       xTemp = xTemp.Substring(xTemp.IndexOf(',') + 1).Replace(";", "");

                       string obTemp = Ob[0].Substring(Ob[0].IndexOf(',', 3) + 1);
                       obTemp = obTemp.Substring(obTemp.IndexOf(',') + 1);
                       obTemp = obTemp.Substring(0, obTemp.IndexOf(','));

                       if (xTemp.Equals(obTemp) && (x.Substring(x.IndexOf(',', 3) + 1).Contains(Tab)))
                       {
                           if (!rel.Contains(s) && !s[0].Substring(x.IndexOf(',', 3) + 1).Contains("G5ZMN"))
                           {
                               rel.Add(s);
                           }
                       }
                   }
                }
            }
        }
        return rel;
    }

SO是ArrayList,我放置了我的记录数组(有来自DB的数组)。 在这里,我需要找到与我选择的对象相关的对象。

问题是当我使用像2MB这样的文件时,速度不够快。 (我已经用子串替换了Splits函数(它们比删除我检查它更快)。

但我的表现还不够。

你知道我怎么能更快地做到这一点? 我在SubStrings上丢失了大部分CPU功率并进行了更换,但如果我能更快地完成它,我仍然不知道。

2 个答案:

答案 0 :(得分:3)

这不是100%的解决方案,因为我没有您想要接收的元素的确切描述

 private IEnumerable<string> ReadData(string filepath)
 {
   var res = new List<string>( );
   var fileInfo = new FileInfo( filepath );

   if( !fileInfo.Exists )
   {
     throw new ArgumentException( "No file exist with the path " + filepath,
                                  "filepath" );
   }

   var fileStream = fileInfo.Open( FileMode.Open,
                                   FileAccess.Read );
   var file = new StreamReader( fileStream,
                                Encoding.UTF8 );
   string lineOfText;
   while( ( lineOfText = file.ReadLine( ) ) != null )
   {
     var pattern = new Regex( @"^[\w]{2},[\w]{0,},[\w]{1,},([\w]{1,})(?:,[\w]{0,},[\w]{1,}){0,1};$");

     var match = pattern.Match( lineOfText );
     if( match.Success )
     {
       res.Add( match.Groups[ 0 ].Value );
     }
     else
     {
       // Handle lines with wrong format
     }
   }

  return res;
}

解释模式:

^(锚定到字符串的开头)
&#34; \ w&#34;中的任何字符 恰好2倍

&#34; \ w&#34;中的任何字符 至少0次

&#34; \ w&#34;中的任何字符 至少1次

Capture =&gt;结果的元素
  &#34; \ w&#34;中的任何字符   至少1次
结束捕获
非捕获组
  ,
  &#34; \ w&#34;中的任何字符   至少0次
  ,
  &#34; \ w&#34;中的任何字符   至少1次
结束捕获
至少为0,但不超过1倍 ; $(锚定到字符串结尾)

答案 1 :(得分:1)

首先,字符串在C#中是不可变的。每次调用substring或replace方法时,都会创建一个新字符串。请尝试使用StringBuilder

其次你将一大块字符串直接加载到内存中,考虑使用像StreamReader

这样的东西

最后,您应该使用Regex进行模式匹配。