参考書を読んだ所、dbmデータベースは
データの検索・削除等を行う場合に速くて良いとありました。
ここで質問なのですが、データベースのデータを変更せず
データの参照のみを必要とする場合、
外部ファイル化して同じ効果を得られる別の方法…
例えば、ハッシュ配列をそのままdb.txtに保存して
require 'db.txt';
としてみたり、
sub OKWeb {
$OKWeb{'123'} = 'あいう';
~
return $OKWeb{$_[0]};
}
としてみたりといった方法と比べても速いのでしょうか。
また上記の方法以外にもっと速くデータを参照できる方法がありましたら教えて下さい。
No.1ベストアンサー
- 回答日時:
データのサイズや参照の仕方によるのではないでしょうか。
比較的小さなデータから1レコード取り出すようなときは、
大抵の場合ハッシュでも充分かと思います。場合によっては
*DBM_Fileよりも高速でしょう。
ただ、ハッシュの式を外部ファイルにしろサブルーチンにしろ
埋め込んでおいて読ませる場合、Perlがその文を解釈、評価する
時間が掛かることにご注意ください。つまりあまりデータがでかいと、
いつまでたってもそのファイルをがらがら読んでて終わらないよ、
ということもあり得るわけです。もちろんすべてを読みこむのに
必要なメモリも消費しますね。
読みこんだあと全部ソートしたいとか集計したいとかの
目的があるならメモリに読みこむ必要があるでしょうが、
たくさん読みこんだ挙句に参照するデータはひとつ二つだけ…といった
ことになるのだったら、*DBM_Fileなどを利用して外部ファイルに置いて
おいて、必要な部分だけ読みに行く方が有効でしょう。
他に、検索がより複雑になるのだったらRDBMSなどにお任せしたほうが
楽でしょうし、逆にデータが必ず順番に並んでいてサイズも固定長
にしておけば読みこむべき場所が「データ番号 * データサイズ」で一発
でseekできるから速い、なんてテクニックが使える状況もあるでしょう。
あるいはひとつひとつ検索するのを10回繰り返すより、
ひとつ検索したあとはそこから続けて10レコード分まとめて
読みこんじゃえばいい、というような構造のファイルを作れるとか。
(まあ実際、*DBM_Fileの中には上記のようなテクニックを使っている
ものもあると思います。多くの人が改良し合ったコードの方が効率が
良いでしょうから、もし自前のものを書くおつもりならその前にいろいろと
調査されることをお薦めします)
というわけで、速いかどうかは、データの構造ややることによる、と
お答えします。月並みで申しわけありません。
なお、SDBM_Fileなどはファイルサイズの制限があったりします。
perldoc AnyDBM_Fileなどをご覧ください。
詳しく、丁寧なご回答ありがとうございました。
疑問が解決しました!
本当はポイントを全部つけたかったのですが
同一人物へのポイントは駄目なんですね。すいません。
ありがとうございました。
No.2
- 回答日時:
おわかりのことでしょうが老婆心ながら補足します。
ハッシュは優れたデータ格納方法ですが、作成時には各キーの
ハッシュ値を計算して、対応するバケットにデータを突っ込んでおく、
またPerlの場合要素数がある程度増えると自動的にバケットの数を
増やす仕組みになってますけど、そういったもろもろの処理の時間が、
わずかながらでも掛かっていることにご注意ください。
DBファイルの場合その作成時にこれらの処理をまとめて行っておく
(インデックスを張るような場合)と考えると、数百件のデータを
頻繁に呼び出すようなときはやっぱりDBを使うか、データ形式に
特化した格納方法を使う方が有利です。
また、例としてお書きになったサブルーチンを使うほうは、呼び出すたびに
毎回代入し、ハッシュ作成を行うので、データが少ない間ならばいいですが多くなる
ほどとても遅くなるでしょう(一度しかそのサブルーチンを呼ばない
ならまた話は別です)。
あと、「全部ソートしたいとか集計したいとかの目的があるなら
メモリに読みこむ必要がある」と書きましたが、集計する場合は
1レコード読んでは集計して、そのレコードを廃棄して次のレコード
を読みこめばいいですね。メモリの節約にもなります。
[蛇足]
よく初心者の方のプログラムで見かけるのが
my @data = <DATA>;
でファイルを丸ごと読んでしまう方法ですが、これはファイル
が小さいうちはいいでしょうけど、大きくなるとその分メモリを
消費するわけですから、あまり望ましいとはいえません。
(カウンタのCGIサンプルから来てるのかな?なぜみな一様にこんな
書き方をするのか不思議です)
while (<DATA>) {
}
で1行ずつ処理すべきです。多少早ければメモリなんか…という
気持ちもわかりますが、あまりメモリ消費量が多くなればOSが
メモリのスワップアウトでがらがらとディスクの読み書きを始め、
全体が極端に重くなるでしょう。メモリ消費も少ないのに越したことは
ありません。
本題からはずれてしまいました。すいません。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- JavaScript Q&Aの掲示板を作成していてヤフー知恵袋やgoo質問のように質問ごとにURLを生成したい 5 2023/08/04 01:22
- Excel(エクセル) アウトラインの小計のやり方 1 2023/03/20 11:51
- ドライブ・ストレージ 古い外付けHDDから新品外付けHDDへのデータ移行方法 (Mac) 2 2022/12/11 02:01
- その他(データベース) pythonでsqlight勉強中、クエリー結果の利用法教えて下さい 1 2022/04/28 20:38
- Visual Basic(VBA) 複数ファイルのデータの統合について 12 2022/05/14 12:03
- Excel(エクセル) 【VBA】指定フォルダに格納中のテキストファイルをエクセルで処理し結果のエクセルを新規フォルダに保存 1 2022/03/25 14:19
- Visual Basic(VBA) VBAでの共有パスにつきまして 1 2023/03/04 17:24
- Visual Basic(VBA) 列と行の名前(重複あり)が交差するセルに、データを入力したい 2 2022/06/25 22:42
- Excel(エクセル) エクセルで沢山のレコードの最後に追記するには? 7 2023/04/10 13:27
- フリーソフト 色々な形式の個人情報を後で参照しやすいようWindow10で管理したいのですが、どんな方法があるの? 1 2023/04/29 16:46
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
VBAでCSVファイルを途中行まで...
-
VBAでCSVファイルの特定行を書...
-
openした後、closeしないでプロ...
-
JavaでCSVファイルを高速に読む...
-
__DATA__の意味
-
vNoteのBODY部の取得(長めです)
-
MATLABでのwhile文の条件について
-
VB6.0でDB接続する際に切断時の...
-
CSVが可変長の場合の検索方法
-
拡張子 ”log” と ” dat” の違い
-
ExcelをCSV書き出す場合のシー...
-
プログラミング(流れ図とコー...
-
バッチファイルの作り方(CSV→...
-
close()で例外が投げられる理由
-
batファイルでrenameができませ...
-
VBAコードを張り付け後のエクセ...
-
ListBoxのデータを高速でファイ...
-
至急お願いします。C言語で.img...
-
タブの色を変更する方法
-
vba dir の相対パス
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
VBAでCSVファイルの特定行を書...
-
ExcelをCSV書き出す場合のシー...
-
openした後、closeしないでプロ...
-
VBAでCSVファイルを途中行まで...
-
VBAで巨大なファイルの途中から...
-
ReadLineでの読み出し行を指定する
-
JavaでCSVファイルを高速に読む...
-
MATLAB グローバル変数の宣言
-
エクセルVBA コードが同じでも...
-
Perlの変数に文字数制限(容量...
-
perlで、後ろの行を読んで、前...
-
C言語でのファイルのデータ更...
-
2つのCSVファイルをマッチング
-
VB6.0でDB接続する際に切断時の...
-
CSVが可変長の場合の検索方法
-
perlで容量の大きいCSVファイル...
-
1ファイルずつ読み込みたい
-
VBScriptでファイル保存先のデ...
-
perl で googleAPIを呼び出す...
-
C#でCSVファイルを逐一更新したい
おすすめ情報