- ベストアンサー
CSVファイルを読み込む際の構造体の使用は効果的か?
- CSVファイルを読み込んで計算する際に、構造体に格納するかどうか悩んでいます。
- CSVファイルには最大86400行、最大6000列のデータがあります。
- 構造体を使用するとメモリ使用量が増える可能性がありますが、後ほど拡張する際に便利です。しかし、直接ファイルから読み込む方法のほうが無難かもしれません。
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
No.2です。 先に示したアクセスパターンはアプリケーションの振る舞いを指しています。 CSVファイルに対してどのようなアクセスが必要になるかは、この場合計算クラスがどのような順番でデータを処理するかで決まります。これをアクセスパターンと呼びました。 これに対して最適なアルゴリズムを選択する必要があり、その例を例示しました。 86400行と言うことですので1日分のデータと思われますが、必要な処理とアクセスパターンの例は下記になります。 1日分の各カラムの合計、平均を求める →CSVファイルを先頭から順次読み込み処理する。 1分ごとに過去5分の平均を求める。移動平均。 →多少のランダムアクセスが発生。この分をどこで面倒みるかは検討が必要。 ユーザーからの指定により、任意の条件で検索する。 →ランダムアクセス。条件次第ではDBの使用が必要。 と、アプリケーションの要件でやるべき事が変わってきます。これに応じた最適なアルゴリズムを用意しましょうということです。 CSVファイルを直接1行分返さずに管理クラスを経由することで、この辺りの変動要素を押し込むことができ、拡張された場合に備えます。そんな変動はないということが分かっているならわざわざこんなクラスは必要ではないかも知れません。 で、別の話になりますが、構造体で返すとなると構造体のメンバ数が6000ですね。こちらもあり得ない数字ですので検討が必要そうです。
その他の回答 (3)
- notnot
- ベストアンサー率47% (4900/10361)
Q1:1行ずつ読んで順番に処理できないか(全体を同時に使う必要が無い) YES:→1行ずつ処理する(使用メモリが小さくてすむ) NO:(計算に必要とするデータの順番があらかじめ決められない=ランダムアクセスが必要)→Q2へ Q2:メモリが8GBくらいある and 実行時間の要求がシビア YES:→ファイルを全部メモリに読み込んで処理する(当初想定通り) NO:→データベースにデータを格納して使う データベースはRDBMじゃなくて、1つのキーを指定してアクセスする gdbm とかが速そうで良いんじゃないでしょうか。キーは、struct { int row; int column; } 。 http://archive.linux.or.jp/JM/html/GNU_gdbm/man3/gdbm.3.html
お礼
お礼が遅れてしまって申し訳ありません。 せっかく回答して下さったのに、大変失礼致しました。 今回作ろうとしているものは、1行ずつも処理しますし、あらかじめ決められない処理もいたします。 gdbmは知りませんでした。Linuxは初心者ですので、大変参考になりました。ありがとうございます。
- jx-word
- ベストアンサー率40% (38/94)
構造体を使ってDB的に扱うという考え方は自体は悪くないと思います。そこまでする必要があるかどうかは別にして。 ただこれを単純に構造体配列としてオンメモリで処理するとなるとGBオーダーのメモリを必要としますので、特別な条件がなければメモリの無駄遣いなのでやめておく方が吉でしょう。 ではどうするかというと、データ管理クラスをこさえてそのクラス経由でファイルにアクセスするのがいいと思います。 基本は行単位のデータの構造体を返すということにして、後はデータアクセスパターンに応じて管理クラスの内容を検討します。 ファイル先頭から全行順番にアクセス →単純に1行読み込み、解析して返す。 ファイル先頭からランダムで行アクセス。但し各行1回ずつ。 →行読み込みの際に各行の位置を覚えておき、これを参考に次の読み込み位置を決定する。 完全なランダムアクセス。 →一旦ファイル全体を走査し、行先頭の位置と長さを覚える。これを基にファイルアクセス。 局所性のあるランダムアクセス。 →上記に加え、簡単なキャッシュ機構を詰め込む。 他にも条件次第でバリエーションはいくらでもありそうですが、ぱっと思い浮かんだのはこんな感じです。 このハイブリッドもありますが、まずは一番簡単な方法を実装し、必要に応じて拡張するのもいいかもしれません。 もっとも管理クラスを作成すると拡張性に優れますが、最初に書いたようにそこまでする必要があるのかどうかの検討は重要です。必要もない拡張性は単なる無駄なコストですので。
お礼
詳しいご説明ありがとうございます。 2点質問があります。 上記に示して下さったアクセス方法(4つ)が「管理クラス」の振る舞いのパターンなのでしょうか。 そうだとしたら、計算を行うクラスとは別に、管理クラスはアクセスのパターンを決めるということでしょうか。 すみません、あまりわかっていないため不愉快な気分にさせてしまうかもしれませんが、教えてください。 2点目は、ランダムアクセスする、というメリットは何でしょうか。 下名が知識不足のため発想としてなかったのですが、ランダムにすることによって効率的になるのでしょうか。 詳しいご説明の上、このような質問をしてしまい大変申し訳ないのですが、よろしくお願い致します。
- Siegrune
- ベストアンサー率35% (316/895)
最大行86400行×最大列6000列×4byteとしても、2GBほど食いますが。 特殊な事情(すべての行および列に対する再帰的な演算をする、例えば津波の波形の変化を求め一番早い到達時刻を計算するとか)があれは別ですが、普通は、メモリをムダに食っているといわれてもしかたないです。 構造体に入れること自体はまちがっていないです。 が、普通は、ファイルを1行ずつ読み込み、その1行分の最大列6000列を構造体へ入れるにとどめます。 計算するといわれている内容によっては(すべての列に対して同じ処理をする場合など)、 1行1列ずつ読み込んで処理する方がいいかもしれません。
お礼
早々にコメントありがとうございます。 大変参考になりました。 やりたいことは、「CSV1行から計算に必要な項目を読み込んでパラメータを算出する(3パターンの計算をCSV1行に書き込まれた数値を参照して計算する)」ということです。 全てを構造体に入れてしまうと、やはりメモリを食いますね。
お礼
質問をさせて頂いたのにもかかわらず、お返事が遅れてしまいまして大変申し訳ございません。 詳しいご説明ありがとうございました。 仰るとおり、1日分のデータを扱います。 検討の結果、ランダムアクセスは必要になり、今のところC++のVectorに格納しようかと思っています。 DBを使おうかと思ったのですが、経験がなく、環境的にリスクと考えたためやめました。 C++のVectorをあまり使ったことがないのですが、ランダムアクセスが可能という情報なので、試そうと思います。 ありがとうございました。