2

私は現在、約50000行のテキストファイルを読み取るアプリケーションを開発しています。行ごとに、特定の文字列が含まれているかどうかを確認する必要があります。

現時点では、従来のSystem.IO.StreamReader方法でファイルを 1 行ずつ読み込んでいます。

問題は、テキスト ファイルのサイズが毎回変わることです。いくつかのテスト パフォーマンスを行ったところ、ファイル サイズが大きくなると、1 行の読み取りに時間がかかることに気付きました。

例えば ​​:

5000行
のtxtファイルの読み込み:0:40 10000行のtxtファイルの読み込み:2:54

2 倍の大きさのファイルを読み取るには、4 倍の時間がかかります。100000 行のファイルを読み取るのにどれだけの時間がかかるか想像できません。

これが私のコードです:

using (StreamReader streamReader = new StreamReader(this.MyPath))
{
     while (streamReader.Peek() > 0)
     {
          string line = streamReader.ReadLine();

          if (line.Contains(Resources.Constants.SpecificString)
          {
               // Do some action with the string.
          }
     }
}

状況を回避する方法はありますか: ファイルが大きい = 1 行を読み取る時間が長くなりますか?

4

2 に答える 2

7

これを試して:

var toSearch = Resources.Constants.SpecificString;
foreach (var str in File.ReadLines(MyPath).Where(s => s.Contains(toSearch))) {
    // Do some action with the string
}

これにより、ループの前に値をキャッシュすることで、各反復でリソースにアクセスすることを回避できます。これで解決しない場合は、 KMPContainsなどの高度な文字列検索アルゴリズムに基づいて独自のアルゴリズムを作成してみてください。


注:行を遅延して読み取るFile.ReadLinesを必ず使用してください (同様にFile.ReadAllLinesすべての行を一度に読み取るのとは異なります)。

于 2013-04-19T13:38:01.180 に答える
0

使用するRegEx.IsMatchと、パフォーマンスが向上するはずです。

using (StreamReader streamReader = new StreamReader(this.MyPath))
{
 var regEx = new Regex(MyPattern, RegexOptions.Compiled);

 while (streamReader.Peek() > 0)
 {
      string line = streamReader.ReadLine();

      if (regEx.IsMatch(line))
      {
           // Do some action with the string.
      }
 }
}

ただし、コンパイル済みの正規表現を使用することを忘れないでください。これは、参照できるいくつかのベンチマークを含む非常に優れた記事です。

ハッピーコーディング!

于 2013-04-19T13:37:50.227 に答える