2010-12-11 31 views
1

私はiTextSharpを使用しており、数十万のRTFドキュメントを生成する必要があります。結果ファイルのサイズは5KBから500KBです。これを高速化する方法はありますか? MemoryStream vs FileStream

私は以下の2つのアプローチをリストアップしています - 元のアプローチは必ずしも遅いとは限りませんでしたが、私が必要とする出力文字列を得るためにファイルへの書き込みと取り出しの理由を考えました。私はMemoryStreamを使ってこの他のアプローチを見ましたが、実際には遅くなりました。基本的に出力されたRTFコンテンツが必要なので、不要な書式をクリーンアップするためにそのRTFでいくつかのフィルタを実行できます。データを戻すクエリーは非常に速く見えます。元のアプローチファイルを使用して1000ファイル(実際には2000個のファイルが作成されます)を生成するには、約15分かかります。同様に、2番目のアプローチでは約25-30分かかります。私が実行したファイルは平均約80KBです。

2番目の方法に問題がありますか?最初のものより速く、遅くないように思えます。

オリジナルのアプローチ:

RtfWriter2.GetInstance(doc, new FileStream(RTFFilePathName, FileMode.Create)); 
doc.Open(); 

    //Add Tables and stuff here 

doc.Close(); //It saves a file here to (RTFPathFileName) 

StreamReader srRTF = new StreamReader(RTFFilePathName); 
string rtfText = srRTF.ReadToEnd(); 
srRTF.Close(); 

    //Do additional things with rtfText before writing to my final file 

新しいアプローチ、それをスピードアップしようとしているが、これは早く実際の半分である:

MemoryStream stream = new MemoryStream(); 
    RtfWriter2.GetInstance(doc, stream); 
    doc.Open(); 

    //Add Tables and stuff here 

    doc.Close(); 

    string rtfText = 
    ASCIIEncoding.ASCII.GetString(stream.GetBuffer()); 
    stream.Close(); 


     //Do additional things with rtfText before writing to my final file 

第二のアプローチを私がしようとしている私がここで見つける: iTextSharp - How to generate a RTF document in the ClipBoard instead of a file

+0

処理中のファイルのサイズはどれくらいですか?それほど大きくない場合は、それほど大きな違いはありません。それが大きければ、あなたのシステムをあまりにも悪化させる場合は、メモリ内で処理したくないかもしれません。 – phillip

+0

お返事ありがとうございます。私は出力する必要がある約400,000ファイルを持っています - 5KBと500KBの間。私はiTextSharpを使用してSQLクエリからRTFコンテンツを生成しています。 – user53885

+0

Memorystreamを再利用します。すなわち、それを一度割り振り、それをその間の内容をクリアするすべてのファイルに使用する。 – CodesInChaos

答えて

3

結果のストリームのサイズはどれくらいですか? MemoryStreamは成長中に大量のメモリコピー操作を実行するため、大きな結果を得るにはFileStreamと比較して小さなチャンクでデータを書き込むのにかなりの時間がかかります。

問題が発生しているかどうかを確認するには、MemoryStreamのサイズをいくつか大きな値に設定し、コードを再実行します。

修正するには、最初にメモリストリームを事前に拡張するか(おおよその出力を知っている場合)、または成長時に異なるスキームを使用する独自のストリームを書き込むことができます。また、一時的なファイルを使用することは、あなたの目的のために十分であるかもしれません。

0

アレクセイ氏によると、おそらく実際には、いつもMemoryStreamが作成されており、毎回メモリが大きくなるにつれてメモリを連続的に再配置しています。 1つのストリームだけを作成して、すべての書き込みの前に最初にリセットしてみてください。

また、私はstream.GetBuffer()も新しいメモリを返すと思いますので、同じStreamReaderをMemoryStreamで使用してみてください。

あなたのコードはパラレル化が容易なので、Paralel ExtesionsまたはTreadPoolを使用して実行することができます。

これはちょっと変わったようですが、あなたのテキストをストリームのバイトとして書いていて、このストリームをバイトとして読み込んでテキストに変換しています。ドキュメントをテキストとして直接保存することはできませんか?

0

MemoryStreamはファイルに関連付けられていないため、ファイル名の概念はありません。基本的に、あなたはそれをすることはできません。

間違いなくキャストできません。横向きではなく下向きにだけ上向きにキャストすることができます。可視化する:

Stream 
     | 

| | FileStream MemoryStream タイプチェックを介して、MemoryStreamをStreamにキャストし、StreamをMemoryStreamにキャストすることができます。 FileStreamをMemoryStreamに渡すことはありません。それは、犬が動物で、象が動物であると言っているように、犬を象に投げることができます。

MemoryStreamをサブクラス化し、Nameプロパティ(値を指定する)を追加できますが、FileStreamとYourCustomMemoryStreamの間に共通性はなく、FileStreamは既存のインターフェイスを実装していません名;呼び出し元は明示的に両方を個別に処理するか、ダックタイピングを使用する必要があります(おそらくダイナミックまたはリフレクションを介して)。

もう1つのオプション(おそらく簡単です)があります:データを一時ファイルに書き込む。そこからFileStreamを使用してください。 (後で)ファイルを削除します。

関連する問題