C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[9]: テキストファイルの高速な読み込み


(過去ログ 38 を表示中)

[トピック内 20 記事 (1 - 20 表示)]  << 0 >>

■19771 / inTopicNo.1)  テキストファイルの高速な読み込み
  
□投稿者/ カレー (3回)-(2008/05/29(Thu) 18:30:31)

分類:[.NET 全般] 

開発環境
Visual Studio 2005 SP1 C#
Windows XP


現在、C#を使いサーバのログを解析するプログラムを作っています。

その中で、ログファイルを読み込む処理を行っているのですが、
1つのログファイルで1GB近くになる物もあり、読み込みに時間がかかっています。
現在よりも効率的にファイルの読み込みができれればと思うのですが、
何かアドバイスありましたらお願いいたします。

現在は以下のようになっています。

///ファイルを開いて解析
using (StreamReader sr = new StreamReader(fileName, Encoding.GetEncoding("Shift_JIS")))
{
    while ((line = sr.ReadLine()) != null)
    {
        //ログ解析実行
    }
}

読み込むログは一般的なapacheのログやpostfixのログです。

引用返信 編集キー/
■19772 / inTopicNo.2)  Re[1]: テキストファイルの高速な読み込み
□投稿者/ Jitta on the way (102回)-(2008/05/29(Thu) 18:48:45)
No19771 (カレー さん) に返信
 
> ///ファイルを開いて解析
> using (StreamReader sr = new StreamReader(fileName, Encoding.GetEncoding("Shift_JIS")))
> {
>     while ((line = sr.ReadLine()) != null)
>     {
>         //ログ解析実行
>     }
> }


このコードだと、
ファイルの「読み込み」に時間がかかっているのか、
ログの「解析」に時間がかかっているのか、
判別できないと思います。


読み込みながら解析しているので、
「ファイルの読み込み」とは、言えないと思います。

引用返信 編集キー/
■19774 / inTopicNo.3)  Re[2]: テキストファイルの高速な読み込み
□投稿者/ カレー (4回)-(2008/05/29(Thu) 19:01:26)
No19772 (Jitta on the way さん) に返信
> このコードだと、
> ファイルの「読み込み」に時間がかかっているのか、
> ログの「解析」に時間がかかっているのか、
> 判別できないと思います。
>
>
> 読み込みながら解析しているので、
> 「ファイルの読み込み」とは、言えないと思います。

解析部分は置いておいてください。
単純にメッセージを表示するだけの処理とでも置き換えていただいて結構です。
あくまで、読み込みに関する質問と捉えてください。
引用返信 編集キー/
■19775 / inTopicNo.4)  Re[2]: テキストファイルの高速な読み込み
□投稿者/ なちゃ (125回)-(2008/05/29(Thu) 19:03:16)
前方読み込み用オプションつけたらちょっとくらいは変わるかも。
あるいは非同期読み込みで解析しながら読む手もあると思うけど、
それでどの程度変わるかというと何とも言えません。

デフォルトのバッファで十分でほとんど変わらないかも知れません。

引用返信 編集キー/
■19776 / inTopicNo.5)  Re[1]: テキストファイルの高速な読み込み
□投稿者/ 渋木宏明(ひどり) (769回)-(2008/05/29(Thu) 19:13:32)
渋木宏明(ひどり) さんの Web サイト
一括読み込みやブロック単位での読み込みができないようなら、バッファを増やすくらいしかないかな。

引用返信 編集キー/
■19777 / inTopicNo.6)  Re[3]: テキストファイルの高速な読み込み
□投稿者/ カレー (5回)-(2008/05/29(Thu) 19:18:26)
レスありがとうございます。
No19775 (なちゃ さん) に返信
> 前方読み込み用オプションつけたらちょっとくらいは変わるかも。
> あるいは非同期読み込みで解析しながら読む手もあると思うけど、
> それでどの程度変わるかというと何とも言えません。
>
> デフォルトのバッファで十分でほとんど変わらないかも知れません。
>
ちょっと試してみます。
前方読み込み用オプションというのはPeekでしょうか?
今回のコードの場合、
sr.Peek()
という感じになると思うのですが、どの位置に入れるものなのでしょうか?
よろしければご教授ください。

///ファイルを開いて解析
using (StreamReader sr = new StreamReader(fileName, Encoding.GetEncoding("Shift_JIS")))
{
while ((line = sr.ReadLine()) != null)
{
//解析前のここに入れるのでしょうか??
//ログ解析実行
}
}

アドバイス頂いた
> あるいは非同期読み込みで解析しながら読む手もあると思うけど、
は時間があれば試してみようと思います。

引用返信 編集キー/
■19778 / inTopicNo.7)  Re[2]: テキストファイルの高速な読み込み
□投稿者/ カレー (6回)-(2008/05/29(Thu) 19:23:46)
No19776 (渋木宏明(ひどり) さん) に返信
> 一括読み込みやブロック単位での読み込みができないようなら、バッファを増やすくらいしかないかな。
>
大きいファイルになると1GB超えるものもあるので、一括は厳しそうです。
バッファを増やすというのは、C#の場合どのように行うのでしょうか?
よろしければご教授ください
引用返信 編集キー/
■19779 / inTopicNo.8)  Re[3]: テキストファイルの高速な読み込み
□投稿者/ なちゃ (126回)-(2008/05/29(Thu) 19:27:18)
>前方読み込み用オプションというのはPeekでしょうか?

FileOptions.SequentialScanのことです。
StreamReaderだけでは指定できないので、FileStreamを明示的に使用する必要がありますが。

引用返信 編集キー/
■19781 / inTopicNo.9)  Re[4]: テキストファイルの高速な読み込み
□投稿者/ カレー (7回)-(2008/05/29(Thu) 19:44:43)
No19779 (なちゃ さん) に返信
> >前方読み込み用オプションというのはPeekでしょうか?
>
> FileOptions.SequentialScanのことです。
> StreamReaderだけでは指定できないので、FileStreamを明示的に使用する必要がありますが。
>
レスありがとうございます。
MSDN見ながらコーディングしてみます。
引用返信 編集キー/
■19782 / inTopicNo.10)  Re[3]: テキストファイルの高速な読み込み
□投稿者/ 渋木宏明(ひどり) (770回)-(2008/05/29(Thu) 19:52:45)
渋木宏明(ひどり) さんの Web サイト
> バッファを増やすというのは、C#の場合どのように行うのでしょうか?

StreamReader あるいは FileStream のそれぞれに、バッファサイズを引数にとるコンストラクタがあるので、それを使います。
引用返信 編集キー/
■19783 / inTopicNo.11)  Re[4]: テキストファイルの高速な読み込み
□投稿者/ カレー (8回)-(2008/05/29(Thu) 20:08:16)
No19782 (渋木宏明(ひどり) さん) に返信
>>バッファを増やすというのは、C#の場合どのように行うのでしょうか?
>
> StreamReader あるいは FileStream のそれぞれに、バッファサイズを引数にとるコンストラクタがあるので、それを使います。
レスありがとうございます。
了解いたしました。
FileStreamで試してみます。
引用返信 編集キー/
■19785 / inTopicNo.12)  Re[5]: テキストファイルの高速な読み込み
□投稿者/ 中博俊 (1304回)-(2008/05/29(Thu) 20:26:00)
中博俊 さんの Web サイト
いろんなファイルサイズや設定で見てもらえるとわかりますが、えてしてバッファを増やせば速くなるかというとそうでもないです。
そんなに増やしても意味はないと思いますが、個別のコードによるのでお試しあれ。
引用返信 編集キー/
■19787 / inTopicNo.13)  Re[6]: テキストファイルの高速な読み込み
□投稿者/ カレー (9回)-(2008/05/29(Thu) 20:36:22)
No19785 (中博俊 さん) に返信
> いろんなファイルサイズや設定で見てもらえるとわかりますが、えてしてバッファを増やせば速くなるかというとそうでもないです。
> そんなに増やしても意味はないと思いますが、個別のコードによるのでお試しあれ。
助言ありがとうございます。
バッファを調整して試してみようと思います。

引用返信 編集キー/
■19788 / inTopicNo.14)  Re[1]: テキストファイルの高速な読み込み
□投稿者/ NyaRuRu (41回)-(2008/05/29(Thu) 20:37:16)
2008/05/29(Thu) 20:40:31 編集(投稿者)

No19771 (カレー さん) に返信
> その中で、ログファイルを読み込む処理を行っているのですが、
> 1つのログファイルで1GB近くになる物もあり、読み込みに時間がかかっています。
> 現在よりも効率的にファイルの読み込みができれればと思うのですが、

とりあえず最初に限界を把握しておいた方が良いですよ.シーケンシャルな読み取りが 20 MB /sec の環境で,1 GB のファイルを扱うとき,50 秒以下を目指してもそれは無理というものです.
もう既に理論値の 80% ぐらいの性能が出ているのであれば,あとはやたら苦労してせいぜい 10% ちょっと性能が向上する程度ですよ.

シーケンシャルなファイル読み込みに関しては,以下の論文で非常に詳しく分析されていて,「より効率的な読み込み」を目指すのであれば大変参考になります.
http://arxiv.org/ftp/cs/papers/0502/0502012.pdf
ただこの論文は,「RAID などでどんどんハードウェア性能が向上していったとき,ソフトウェア側が足を引っ張らないようにするにはどうするべきか?」というのがそもそもの動機になっていて,そもそもハードウェアが足を引っ張るような状況では効果がありません.論文では 800 MB/sec という環境で議論しています.ハードウェアがそれぐらいすごければ,ソフトウェアでもがんばり甲斐が出てくるわけです.

ご参考までに,この論文については,以下でも考察を行っています.よろしければどうぞ.
http://d.hatena.ne.jp/NyaRuRu/20080306/p1
引用返信 編集キー/
■19789 / inTopicNo.15)  Re[7]: テキストファイルの高速な読み込み
□投稿者/ カレー (10回)-(2008/05/29(Thu) 20:44:05)
FileStreamでコーディングを行っています。
FileOptions.SequentialScanを利用しているサンプルがみつからず、難航しているのですが
FileStreamで読み込んだ場合、byteの配列で改行を無視してバッファ分読み込むことになりますよね?
改行まで(1行分)読み込むというコーディングは出来ないでしょうか?

引用返信 編集キー/
■19790 / inTopicNo.16)  Re[8]: テキストファイルの高速な読み込み
□投稿者/ なちゃ (127回)-(2008/05/29(Thu) 20:58:32)
No19789 (カレー さん) に返信
> FileStreamでコーディングを行っています。
> FileOptions.SequentialScanを利用しているサンプルがみつからず、難航しているのですが
> FileStreamで読み込んだ場合、byteの配列で改行を無視してバッファ分読み込むことになりますよね?
> 改行まで(1行分)読み込むというコーディングは出来ないでしょうか?

FileStreamからStreamReaderを作れば後は同じ感じでいいはずですよ。
※StreamReaderのコンストラクタにFileStreamを渡す

引用返信 編集キー/
■19799 / inTopicNo.17)  Re[3]: テキストファイルの高速な読み込み
□投稿者/ Jitta on the way (104回)-(2008/05/30(Fri) 07:38:13)
No19774 (カレー さん) に返信
> ■No19772 (Jitta on the way さん) に返信
>>このコードだと、
>>ファイルの「読み込み」に時間がかかっているのか、
>>ログの「解析」に時間がかかっているのか、
>>判別できないと思います。
>>
>>
>>読み込みながら解析しているので、
>>「ファイルの読み込み」とは、言えないと思います。
>
> 解析部分は置いておいてください。
> 単純にメッセージを表示するだけの処理とでも置き換えていただいて結構です。
> あくまで、読み込みに関する質問と捉えてください。

sr.ReadLine が遅いと、どうやって判断しましたか?
「出力」というのがコンソールなら、コンソールに出力することが、かなり遅いですよ?



ディスクからメモリに持ってくるのが遅いのか。
ログ ファイルが大きいので、全部を処理するのに時間がかかるのか。

どっち?
引用返信 編集キー/
■19802 / inTopicNo.18)  Re[4]: テキストファイルの高速な読み込み
□投稿者/ カレー (11回)-(2008/05/30(Fri) 08:41:27)
No19799 (Jitta on the way さん) に返信
> ■No19774 (カレー さん) に返信
>>■No19772 (Jitta on the way さん) に返信
> >>このコードだと、
> >>ファイルの「読み込み」に時間がかかっているのか、
> >>ログの「解析」に時間がかかっているのか、
> >>判別できないと思います。
> >>
> >>
> >>読み込みながら解析しているので、
> >>「ファイルの読み込み」とは、言えないと思います。
>>
>>解析部分は置いておいてください。
>>単純にメッセージを表示するだけの処理とでも置き換えていただいて結構です。
>>あくまで、読み込みに関する質問と捉えてください。
>
> sr.ReadLine が遅いと、どうやって判断しましたか?
> 「出力」というのがコンソールなら、コンソールに出力することが、かなり遅いですよ?
>
> ディスクからメモリに持ってくるのが遅いのか。
> ログ ファイルが大きいので、全部を処理するのに時間がかかるのか。
>
> どっち?

遅いと判断したのではありません。
前述しているように、ログファイルのサイズも大きいので、時間がかかるのは当然というのは承知です。
現在の方法より効率的に読み込むテクニック等あれば教えて頂きたかったという事です。
引用返信 編集キー/
■19803 / inTopicNo.19)  Re[9]: テキストファイルの高速な読み込み
□投稿者/ カレー (12回)-(2008/05/30(Fri) 08:42:02)
No19790 (なちゃ さん) に返信
> ■No19789 (カレー さん) に返信
>>FileStreamでコーディングを行っています。
>>FileOptions.SequentialScanを利用しているサンプルがみつからず、難航しているのですが
>>FileStreamで読み込んだ場合、byteの配列で改行を無視してバッファ分読み込むことになりますよね?
>>改行まで(1行分)読み込むというコーディングは出来ないでしょうか?
>
> FileStreamからStreamReaderを作れば後は同じ感じでいいはずですよ。
> ※StreamReaderのコンストラクタにFileStreamを渡す
>
レス&助言ありがとうございます。
そういう事ですね。
やってみます。
引用返信 編集キー/
■19805 / inTopicNo.20)  Re[9]: テキストファイルの高速な読み込み
 
□投稿者/ カレー (13回)-(2008/05/30(Fri) 09:15:44)
No19790 (なちゃ さん) に返信
> FileStreamからStreamReaderを作れば後は同じ感じでいいはずですよ。
> ※StreamReaderのコンストラクタにFileStreamを渡す
> 

以下のように実装してみました。
動作していますが、コーディングミス等あればご指摘ください。
正しいようであれば、バッファサイズを調節し、ベンチマークを取ってみたいと思います。

using (FileStream fs = new FileStream(FileName, FileMode.Open, FileAccess.Read, FileShare.Read, 1024, FileOptions.SequentialScan))
{
  using (StreamReader sr = new StreamReader(fs, Encoding.GetEncoding("Shift_JIS")))
  {
    while ((line = sr.ReadLine()) != null)
    {
      //ログ解析実行
    }
  }
}

引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -