|
perlでテキスト処理をしていますが、有るリストをキーとしたハッシュ を生成したんですが、そのキーとなるファイルのサイズが110Mb程、キー数 (レコード数)は約1000万弱のレコードが有ります。 そのハッシュのキーを使い別のCSVのフィールドの中に同じキーが存在 する場合に必要な処理を行なっています。 if(exists $KEY{$csv_key_field}){ 処理 } で、実際に動かすと500Mbのメモリを使い切り(何故?)、1Gbのスワップ さえも使いきり止まってしまいます。 根本的にこのアルゴリズム自体が悪いのか、それとも何かメモリ使用量を 抑える解決方法があるのか教えてください。 ちなみに、キーとなるデータを配列に格納して grep で検索するとさらに べらぼうに時間が掛かります。 具体的には2つのリストの合成処理なんですが、このくらいの規模になると DBに置き換えて処理した方が良いのでしょうか? (最終的には何らかのDBに格納されるそうです) もちろん、変数は可能な限り局所化しています。(つもりです(^^;) もっと言えば、上記は最大サイズのリストではありますが、キーリストは 複数あり、それらを順繰りに処理しています。 どうぞお助けくださいm(_ _)m |
|
>>3319 スナフキン > そのキーとなるファイルのサイズが110Mb程、キー数(レコード数)は > 約1000万弱のレコードが有ります。 全体のデータ容量がわからないですが、仮に 300MB 程度だとしても、 1.5GB 喰い尽くしてもおかしくないかなぁとは思います。 perl の内部構造は知りませんが、スカラー 1つ、配列の一要素、 ハッシュ 1キーなど、それぞれに必ず何バイトかずつ管理用データを perl が保持しているからです。 実感としては、100MB 程度でもデータの持ち方次第ではまともに 動かないこともあるんじゃないかと思います。 > このくらいの規模になるとDBに置き換えて処理した方が良いので > しょうか? perl でもがんばれば何とかなるかもしれませんが (実データはファイルに 保存し、ハッシュにアクセスされるたびに tie でそのファイルを見にいくとか)、 1. データが固定長 (もしくは最大長が決まっている) 2. CSV の項目名や項目長が変わる可能性は少ない 3. 処理内容が変わる可能性が少しでもある (この条件に引っかかるレコードは除外する、とか) であれば、DB に突っ込んだ方がよろしいのではないでしょうか。 わたしならそうします。 項目名や項目長も変わるかもしれないなら、DBD::CSV モジュールとか (使ったことないですけど)。 |