2012-04-05 14 views
0

私は非常に大きなCSVファイル〜800,000行を持っています。私はスクリプトをスピードアップするためにこのファイルをparellelで処理しようとします。ルビーを使用してCSVファイルを並列処理する

Rubyを使用してファイルをn個の小さな断片に分割するにはどうすればよいですか?

+0

処理の高価な部分は何ですか?それは主にCSV自体の解析ですか、それとも後続の計算ですか?計算は実際に並列化に適しているのですか、それとも以前の入力に依存していますか?レコードセパレータを簡単に識別できますか(たとえば、各レコードが「\ n」で終わっているか、フィールドに「\ n」埋め込まれている可能性がありますか)? – dbenhur

答えて

2

CSVファイルをチャンクに分割するのは順番ですが、各チャンクはCSVヘッダーの最初の行を保持する必要があります。

UNIX 'split'はそれをカットしません!

最初の行を読み込んで変数に格納し、次のN行を新しい部分CSVファイルに配布する小さなRubyスクリプトを作成する必要がありますが、最初にCSVヘッダー行をコピーします。

ヘッダーと行の塊で各ファイルを作成したら、Resqueワーカーによる並列処理のためにResqueを使用してこれらのファイルを登録できます。

http://railscasts.com/episodes/271-resque

0

私はこのファイルを多数の小さなファイルに分割するためにlinux splitコマンドを使用します。次に、これらの小さな部品を処理します。

+1

ボトルネックはディスクです。ファイルを別々のディスクに保存しない限り、小さなファイルに分割することはできません。 – pguardiario

+0

が該当する可能性がありますが、ディスクへのアクセスを回避する方法について説明します。複数のスレッドであっても、スレッドが何らかの操作を実行するたびに、各スレッドまたはファイルハンドル位置のファイルハンドルを移動する必要があります。したがって、別々のファイルと別のプロセス(またはスレッド)を使用すると、I/Oに関連するスレッドの中断による待ち時間を最小限に抑えることができます。私が間違っている? – tartar

+2

分割プロセス行ですが、CSVは引用されたフィールドに改行を埋め込むことができるため、改行のみの分割は一般的な場合は控えめです。 – dbenhur

2

CSVファイルについては、これを行うことができます。array(メモリ)またはファイルに保存する行(または分割さライン)により、

open("your_file.csv").each_line do |line| 
    # do your stuff here like split lines 
    line.split(",") 

    # or store them in an array 
    some_array << line 

    # or write them back to a file 
    some_file_handler << line 
end 

は、あなたが小さな部分に大きなファイルを分割することができます。その後、スレッドを使用して各ピースを処理することができます。

threads = [] 
1.upto(5) { |i| threads << Thread.new { do your stuff with file[i] } } 

threads.each(&:join) 

スレッドを安全に保つ責任があります。

希望すると便利です。

更新:

pguardiarioのアドバイスによると、私たちはスタンドのライブラリーからではなく直接ファイルを開くのCSVファイルを使用することができます。

+2

これはcsvファイルを処理するための間違った方法です。代わりにCSVライブラリを使用してください。 – pguardiario

+1

ええ、私たちはcsv libを使うべきです。しかし、恩恵ですか? – Tomato

+1

ほとんどの場合、引用符とヘッダーが必要ですが、詳細はドキュメントをご覧ください。あなたが正しい方法で何かをしたときに得られる良い気持ちも:) – pguardiario

関連する問題