アプリ版:「スタンプのみでお礼する」機能のリリースについて

現在Perlでソフトの管理プログラムを作っています。

1万件くらいまではまま順調に動いていたのですが
現在1万5千件くらいになって表示的にはそこそこ高速なのですが
サーバー(ドリームホストの一番安いの・・・すいませんケチで)が
月に1度程度、極端に遅くなります。
どうも私の巨大データに問題が有るようなのですが・・・

で、サーバーの負荷をすこしでも減らしたいと思っているのです。

現在、検索の場合等は、全1万5千件余りのデーターを
@all_data=<DATA>;
で全読みし、各行の照合作業をした後、結果を出力しています。
これを1000件ごとのファイルに分割し、

1枚目ファイルオープン→@all_data=<DATA>;→結果収集、
2枚目ファイルオープン→@all_data=<DATA>;→結果収集、
           ・ 
           ・
           ・
15枚目ファイルオープン→@all_data=<DATA>;→結果収集、

で、結果を出力

の様に変更した方がサーバー負荷(CPU使用率やメモリー消費)は
少なくなる物でしょうか?

または1行づつ照合作業し、結果を出力、
と言う手も有ると思うのですが・・・。

余り詳しくないので・・・出来ましたら素人向けの回答を背宜しくお願いします。

A 回答 (3件)

まずは、メモリのサイズとファイルのサイズが明確でないと、遅くなる理由があなたのプログラムのせいなのかどうかはわかりません。

件数が一万件から一万5千件になった程度(50%増)で極端に性能が落ちることはあまり考えられません。よっぽどメモリが小さいか、件数の増加とともに処理量が指数関数的に増えるような処理をしているかのどちらかです。
月に一度遅くなるということですが、あなたのプログラムは常時走っているのですか?

1000件に分割した場合、メモリ消費は減りますが、テキストを処理している間のCPUの使用効率は変わりません。1000件であろうと10000件であろうと同じ処理をしているわけですから、実行されている命令列は同じあるいは非常に似ています。似たような命令列が実行されるのであれば、実行中のCPUの使用効率に変化はほとんどありません。ただ、ファイルを分割した場合は、新たにファイルを開くときにデータをメモリにロードするわけで、その間CPUは遊んでいますから、一時的にCPUの負荷は下がります。当然CPUが遊んでいるというこは、処理効率が悪いということであまり好ましいことではありません。

まずは、メモリのサイズとファイルのサイズを明確にしてください。
    • good
    • 0

ドリームホストというのはこれのことですよね。


http://www.dreamhost.com/

やっていることから考えると、SQLiteを使うと良さそうに思います。
http://wiki.dreamhost.com/SQLite

メリット
- CPU使用率が下がります
- メモリー消費も1万5千件全部開いている現状より下がるかもしれません

デメリット
- ちゃんと性能を出すにはリレーショナルデータベースについて勉強しなくてはいけません
- TXTファイルと違ってSQLiteを使わないと中身を読めません
- TXTファイルと違ってファイルサイズは大きくなります。

PerlからSQLiteを使う方法は"Perl SQLite"で検索すると簡単に見つかります。
そのサンプルでもいじりがてら使ってみるとよいでしょう。

...とここで終わると、「全然早くならない。遅くなった」と言われそうなので一応。
あなたがいう"照合作業"をする場合、基本的にSQLというデータベースを操作する言語を使って記述し、Perlで逐一照合するというプログラムは書きません。
例えば、NOが3のものを取り出すというのは、こんな感じで書きます。
select * from music_data where no = 3;
あるいは、種類がJPOPを探す場合、こんな感じで書くかもしれません。
select * from music_data where kind = 'JPOP';
whereで書く条件はANDでつなげて複数記述できます。
select * from music_data where kind = 'JPOP' and no = 3;

また、SQLでちゃんとスピードを出すにはインデックスを設定する必要があります。本の索引のようなものです。本の中で特定の言葉が使われているところを探すとき、本を最初から読んで探さず、本の最後などに付いている索引から探します。これと同じように、データベースにデータを入れた時、予め索引を作っておき、後からすぐに探せるようにします。
"照合作業"を行う項目についてはちゃんとインデックスを設定しましょう。

...まあ、言葉は散りばめましたのであとは検索してみてください。
    • good
    • 0

@all_data=<DATA>;


これは、ファイルの全部を一度読み込むので、最低でもファイルサイズと同じだけのメモリが必要です。
メモリが潤沢ならばいいのですが、状況によっては高負荷となります。

1枚目ファイルオープン→@all_data=<DATA>;→結果収集、
2枚目ファイルオープン→@all_data=<DATA>;→結果収集、
この方法では、ファイルを複数openする必要があります。
データ量自体は同じですが、「ファイルを開く」ためにディスクにアクセスするので、その分のオーバーヘッドがかかり、遅くなったり高負荷になったりする場合があります。

一行ずつ読んで処理をするのが、負荷は軽くて済みます。
速度低下による影響は少ないでしょう。



これより増えるようなら、別質問にあるように、データベースを使うのがよいと思います。
データベースは大量のデータを扱うことを目的としたもので、条件を指定して必要なものだけを受け取る、ということができるので、Perl側の負荷の軽減が期待できます。

素人にも、と言われても簡単に説明できるものではないので、サイトや参考書でデータベースについて勉強してみてください。
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!