2009-06-24 6 views
7

圧縮をテストするためには、理想的にはテキスト、バイナリ、および混合形式の大きなファイルを作成できる必要があります。「自然」の内容の大きなテキスト(1GB以上)とバイナリファイルをすばやく作成するにはどうすればよいですか? (C#)

  • ファイルの内容は完全にランダムでも均一でもないはずです。
    すべて0のバイナリファイルはいいです。全くランダムなデータを持つバイナリファイルも良くありません。テキストの場合、完全にランダムなASCIIシーケンスのファイルは良くありません。テキストファイルには、自然言語やソースコード(XML、C#など)をシミュレートするパターンと頻度が必要です。疑似実テキスト
  • 個々のファイルのサイズは重要ではありませんが、ファイルのセットでは合計が〜8GBである必要があります。
  • ファイルの数を管理可能なレベルに保ちたいと思います.O(10)としましょう。

バイナリファイルを作成するために、私は大きなバッファを新たにし、ループ内でFileStream.Write続いSystem.Random.NextBytesを行い、このようなことができます。

Int64 bytesRemaining = size; 
byte[] buffer = new byte[sz]; 
using (Stream fileStream = new FileStream(Filename, FileMode.Create, FileAccess.Write)) 
{ 
    while (bytesRemaining > 0) 
    { 
     int sizeOfChunkToWrite = (bytesRemaining > buffer.Length) ? buffer.Length : (int)bytesRemaining; 
     if (!zeroes) _rnd.NextBytes(buffer); 
     fileStream.Write(buffer, 0, sizeOfChunkToWrite); 
     bytesRemaining -= sizeOfChunkToWrite; 
    } 
    fileStream.Close(); 
} 

十分な大きさのバッファでは、聞かせての512kと言うと、2GBや3GBを超えるファイルの場合でも比較的高速です。しかし、コンテンツは完全にランダムです。これは私が望むものではありません。

テキストファイルの場合は、Lorem Ipsumを使用して、StreamWriter経由で繰り返しテキストファイルに出力します。内容は非ランダムかつ不均一であるが、多くの同一の反復ブロックがあり、これは不自然である。また、Lorem Ispumブロックは非常に小さく(< 1k)、多くのループと非常に長い時間がかかります。

どちらも私にとってはまったく問題ありません。

私はQuickly create large file on a windows system?の回答を見ました。これらのアプローチは非常に高速ですが、私はファイルをゼロまたはランダムなデータで埋め尽くしていると思います。どちらも、私が望むものではありません。私は必要に応じてcontigやfsutilのような外部プロセスを実行することに問題はありません。

テストはWindowsで実行されます。
新しいファイルを作成するのではなく、ファイルシステムにすでに存在するファイルを使用する方が理にかなっていますか?私は十分に大きいものは分かりません。

既存のファイル(テキストファイルの場合はc:\ windows \ Microsoft.NET \ Framework \ v2.0.50727 \ Config \ enterprisesec.config.cchなど)から開始し、何度もコンテンツを複製するのはどうですか?これは、テキストファイルまたはバイナリファイルで動作します。

現在、私は仕事の種類はありますが、実行には時間がかかります。

他に誰かがこれを解決しましたか?

StreamWriterを使用するよりもはるかに高速にテキストファイルを書き込むことはできますか?

提案?

EDIT:私はより自然なテキストを生成するためにマルコフチェーンという考えが好きです。しかし、スピードの問題にまだ対処する必要があります。

+0

どのような種類のバイナリデータをシミュレーション(画像)しようとしていますか? –

+0

画像に重点を置いていませんが、私はほとんどの画像フォーマットがあらかじめ圧縮されていると思います。データベースファイルやその他のバイナリデータフィードの方が重視されます。 – Cheeso

+0

完全なソースコードを含む最終的なソリューションのサンプル? – Kiquenet

答えて

4

このデータを生成するには、Markov chainプロセスのようなものを探している可能性があります。どちらも確率的(無作為化)であるが、finite state machineに基づいて動作するという点で構造化されている。

確かに、マルコフ連鎖は、人間の言語で準リアルな見た目のテキストを生成するために使用されてきました。一般的に、彼らは適切に分析するのは簡単なことではありませんが、特定の特性を示すという事実は、あなたには十分であるはずです。 (やはり、ページのProperties of Markov chainsセクションを参照してください)。しかし、実際には単純なコンセプトです。おそらく、一般的なマルコフプロセス用のフレームワークを作成し、マルコフプロセスを「鍛える」ために、自然言語またはソースコード(任意のデータをエミュレートしたいもの)を分析することが最善の策です。結局のところ、これはあなたの要件の点で非常に高品質のデータを与えるはずです。これらの膨大なテストデータが必要な場合は、努力する価値があります。

+0

大丈夫、私は研究します。興味深いのは、8GBのデータ*が巨大でしたが、最近ではウェブトラフィック履歴ストア、商品のマルチTBディスクアレイ、S3などでは、8GBはそれ以上に巨大ではありません。 – Cheeso

+0

ええ、そうかもしれません。それでも、計算とI/O時間の点では、今日でも重要です。 – Noldorin

+0

真。 Markov Chainsについて - 私は新しい実装を書こうとは思わない。私が見つけたインプラントはhttp://blog.figmentengine.com/2008/10/markov-chain-code.htmlで非常に良い結果を出しましたが、とても遅かったです。 – Cheeso

10

あなたはいつも自分の小さなWebクローラをコードすることができます... はみんな落ち着いて

UPDATE彼はすでに「時間がかかりすぎる」という解決策を持っていたことを言っていなかった場合、この良い答え、だろう。

クイックチェックhereは、8GBのダウンロードでは比較的長い時間がかかることを示しているようです。

+0

そうすれば、おそらく最も自然なデータが得られます。 –

+0

また、画像もダウンロードできます。 – Benjol

+0

+1。これは私の最初の考えでしたが、私はこのアプローチが「速い」カテゴリーに入るのではないかと疑っています。 – Kirschstein

14

テキストの場合、stack overflow community dumpを使用すると、そこに300メガバイトのデータがあります。それは、私が書いたアプリでデータベースにロードするのに約6分かかります。おそらく同じ時間にテキストファイルにすべての投稿をダンプすると、あなたのアプローチに応じて200〜100万のテキストファイルが簡単に得られます(ソースとxmlが混在しているというボーナスが追加されています)。

また、wikipedia dumpのようなものを使用することもできます。これは、MySQL形式で出荷されるように思われます。

分割可能な大きなファイルを探している場合は、バイナリの目的で、VM vmdkまたはローカルでリッピングされたDVDを使用できます。

編集

マークは、プロジェクトグーテンベルクのダウンロードに言及し、これはまたdownload via bittorrentのために利用可能であるテキスト(およびオーディオ)のために本当に良いソースです。

+3

私はプロジェクトグーテンベルクを調べることに言及するつもりでした。プレーンテキストファイルのほとんどはすでに圧縮されているので、クイックダウンロードになります。 http://www.gutenberg.org/catalog/ –

+0

@マーク、良い点、悪いリンクを追加、ありがとう! –

+0

Wikipediaダンプの一部を使用する圧縮ベンチマークがあります:http://cs.fit.edu/~mmahoney/compression/textdata.html – CesarB

1

テキストファイルの場合は、english word listという文字列を使用して、単語をランダムに取り出すことができます。これは実際の英語のテキストを生成しませんが、私はそれがあなたが英語で見つけるかもしれないものに似た文字の頻度を生成すると思います。

もっと構造化されたアプローチのためには、大きな英語の無料テキストで訓練されたMarkov chainを使用することができます。

+0

私はLorem Ipsumからランダムに1つの単語を選択してこのアプローチをとったが、この方法で大規模なテキストファイルを生成することは退屈なほど遅かった。マルコフ連鎖アプローチは、テキストの厳密な「自然性」に向かって傾いているように思えます。私にとっては、世代の速度より重要ではありません。 – Cheeso

+0

マルコフ連鎖は確かにこれに向かう正しい方法です。彼らは高品質の出力を作り出し、とても*すばやく行います。 – Noldorin

1

Lorem Ipsumを取り出し、出力前に長い文字列をメモリに作成してみませんか?毎回テキストの量を2倍にすると、テキストはO(log n)の割合で展開されます。データの全長を計算してから、新しい文字列/配列にコンテンツをコピーする必要がなくなります。

あなたのバッファはわずか512kなので、設定するものは何であれ、一度にファイルにプッシュできる量なので、書き込む前に多くのデータを生成すればよいだけです。同じテキストを何度も何度も書いているので、最初に作成したオリジナルの512kを使用してください。

3

私は、Windowsディレクトリがおそらくあなたの必要性のための十分な情報源になると思います。テキストの後には、.txtファイルを探しているディレクトリごとに再帰的に実行し、適切なサイズのファイルを取得するのに必要な回数だけ出力ファイルにコピーします。

次に、.exesまたは.dllを検索することによって、バイナリファイルに同様のアプローチを使用できます。

1

Wikipediaは、混在テキストとバイナリの圧縮テストに優れています。ベンチマークの比較が必要な場合、Hutter Prize siteはWikipediaの最初の100Mbに最高水準点を提供することができます。現在の記録は6.26の比率、16メガバイトです。

0

すべてのクイック入力をありがとう。 スピードと「自然さ」の問題を別々に考えることに決めました。自然のテキストを生成するために、私はいくつかのアイデアを組み合わせました。

  • テキストを生成するには、Mark Rushakoffの提案のとおり、project gutenbergカタログのテキストファイルから始めます。
  • ランダムにそのサブセットの1つのドキュメントを選択してダウンロードします。
  • 次に、ダウンロードしたテキストを入力として使用して、suggested by Noldorinというマルコフプロセスを適用します。
  • 例としてPike's economical Perl implementationを使用してC#で新しいMarkov Chainを書きました。一度に1単語のテキストを生成します。
  • 効率的に、純マルコフ連鎖を使用して一度に1グラムのテキストを生成するのではなく、〜1MBのランダムテキストを生成し、ランダムなセグメントを繰り返して取り込みます。

UPDATE:第二の問題については、スピードは - 私はできるだけ多くのIOを排除するためのアプローチを取った、これは5400ミニスピンドルで私の貧弱なラップトップ上で行われています。これにより、問題を完全に再定義することができました。FILEランダムコンテンツを生成するのではなく、ランダムコンテンツです。マルコフ連鎖を囲んでいるストリームを使って、メモリにテキストを生成し、それをコンプレッサにストリームして、8gの書き込みと8gの読み取りを排除することができます。この特定のテストでは、圧縮/復元のラウンドトリップを確認する必要はないため、元のコンテンツを保持する必要はありません。だから、ストリーミングのアプローチは大事にスピードアップするためにうまくいきました。それは必要な時間の80%を削減します。

私はまだバイナリ生成を行う方法を理解していませんが、類似したものになる可能性があります。

ありがとうございました。すべての参考にしていただきありがとうございます。

関連する問題