• 締切済み

Perl 高速でファイルを結合させたい

ある集計データを作成しているのですが、 とにかく遅いです。 下記のソースで、繰り返しファイルをオープンさせ 結合を繰り返しているからでしょうが これを早くするにはどうすればいでしょうか? ※やりたいことは実際はできております。 まず条件として ディレクトリのデータは数年分あり 今回は、4年分の統計を取りたい。 →2018年度、2017年度、2016年度、2015年度 ディレクトリのファイルの数、ファイルの名前は一緒(例は数字ですが、基本名前です) →ファイルの数は15個 →ファイル容量 大きいので1500kbの約2万行 少ないので600kbほど 合計ファイル容量1年分→1mbほど 4年分になると4mb(単純計算) 平均ファイル容量750kbほど my @DATAFILE; my @FILENAME = ("T1","T2","T3","T4","T5","T6","T7","T8","T9","T10","T11","T12","T13","T14","T15"); my $Year = 2018; my $YearM = $Year - 3; for(my $i=0;$i<=$#FILENAME;$i++){ my $FILE = $FILENAME[$i]; chomp($FILE); for(my $pr=$YearM;$pr<=$Year;$pr++){ open(FILE, "<","data/log/$pr/$FILE.txt"); eval{ flock(FILE, 1) }; my @DATASUM = <FILE>; close FILE; push @DATA,@DATASUM; } } どうか改善方法を教えください。

みんなの回答

  • wormhole
  • ベストアンサー率28% (1626/5665)
回答No.3

取りあえず条件がおかしいです。 小さいファイルで600KB、 1年分の15ファイルが全て小さいファイルだったとしても、 600KB x 15 で 9000KB→約9MB ですよ(1ファイルの容量が間違っているのか、1年分の容量が間違っているのかはわかりませんが)。 処理速度には影響しないでしょうが >chomp($FILE); は不要("T1"~"T15"の文字列から末尾の改行を取り除く意味はないですよね。元からないんですから)。 大きいファイルが1500KBで約2万行ということは 平均ファイル容量の750KBだと約1万行ということろでしょうか。 それを60ファイルということですから >push @DATA,@DATASUM; の部分は@DATAに最終的に60万要素のpushをしてることになりませんか? 試していませんが行単位で読み込むのではなくファイル単位でまるまる読み込み連結後にsplitした方が早いんじゃないでしょうか。

  • STICKY2006
  • ベストアンサー率29% (1536/5269)
回答No.2

https://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q11193930196 他のとこでも質問されてるなら、わざわざ自分が書く必要もなさそうなので簡単にだけ。 「どうしてもPerlでやらなければいけない」前提の話なら ・前にも張り付けたけど、わざわざファイル開かんでも、結合するコマンドでくっつけるのを試してみりゃいい ・1行でもコード減らせば処理時間がコンマ秒は減るんだろうから、ソースを見直す とかぐらいでしょうか。 自分なら ・サーバ上でバッチ処理組んどく ・30秒ぐらいじゃ待つ(質問文からは、「高頻度の作業である」とは読み取れなかったので) ぐらいでしょう。多分。 504エラーは、サーバ設定でもいじりゃ、どうにかなるでしょう。

  • STICKY2006
  • ベストアンサー率29% (1536/5269)
回答No.1

>>Perl 高速でファイルを結合させたい Perlである必要性は?? >>とにかく遅いです。 表現が主観すぎます。 「数字」として記載した方がよろしいかと。(で、これをどのぐらいにする必要がある。と。 「そんなに遅いなら、手作業でやったら?6~70ファイル程度なんでしょ?」 と個人的には思ってしまいますし。 >>繰り返しファイルをオープンさせ結合を繰り返しているから オープンしないで結合すりゃいいんじゃないすかね。 ファイルAのお尻にファイルBの内容を追記して、ファイルCを作成する。 ような無料ツールぐらいならゴロゴロと落ちてると思いますよ。 最悪、2万行程度のテキストファイルなら、手作業で「開いてコピって張り付けて」を繰り返したって、そこまで時間かかる作業ではないと思いますし。。。 15ファイルが、4年分。ですよね。死ぬほど多い数じゃない。 ファイル分割・結合 https://www.vector.co.jp/vpack/filearea/win/util/file/spl_mrg コマンドプロンプトの copy コマンドでファイルを結合する https://futuremix.org/2009/10/combile-file-with-copy-command コマンドプロンプトで2つのファイルを結合する http://cmd-pro.com/m_com.html http://q.hatena.ne.jp/1361688412

programstudy11
質問者

お礼

御回答ありがとうございます。 Perlである必要性 →ウェブ上での作業のため 遅い →30秒ほどかかったりひどいときは504エラー 手作業 →手作業ですべて結合した後にオープンでも時間がかかった・・・ です・・・