20

ファイルの読み取りと書き込みを伴うプログラムを作成するのは初めてです。実際、私はこれを行うための最良のテクニックは何であるか疑問に思っています。私の仕事をクラスメートと比較したとき、私たちの論理は互いに非常に異なっているからです。

ご覧のとおり、先生から、ユーザーがレコードを追加、編集、削除できる簡単な生徒リストシステムを作成するように依頼されました。そして彼は、次にプログラムを使用するときにアクセスできるように、すべてのレコードを保存するためのファイルを作成するように要求しました。

この問題に対する私の解決策は、プログラムがメニューを開く前に、内部のすべてのレコードを読み取り、それをarray[]に保存することです。そうすることで、私はすべてのレコードを操作することができました。次に、ユーザーがプログラムを終了する前に、プログラムを同じファイルに保存し、その上のすべてのレコードを上書きします。

私のクラスメートの解決策はこのようなものです。彼女は、レコードを追加するときにファイルにアクセスしてデータを追加し、レコードを編集するときにファイルにアクセスして特定のレコードを編集し、レコードを削除するときにファイルにアクセスしてレコードを削除します。つまり、彼女が行ったことは、彼女が作成したすべての関数に対して、ファイルにアクセスしているということです。

もちろん、両方の作業をコーディングすることは可能です。しかし、数千または数百万のレコードを処理する場合、どちらを使用する方が効率的で効果的か疑問に思います。または、私たちが行ったよりも優れた他の解決策はありますか?たぶんあなたはあなたのファイル処理の経験を私たちと共有することができます...ありがとう。

4

5 に答える 5

14

これは、プログラミングで何度も遭遇する典型的なケースです。速度またはメモリ使用量を最適化する必要がありますか?

そして、そのようなすべての難問のように、「正しい」答えや完璧な解決策はありません。言い換えれば、あなたとあなたのクラスメートは両方とも問題に対するあなたの解決策に正しいです。

すべてのレコードをメモリにロードするソリューションでは、実行時にこれらの各レコードへのアクセスと変更を高速化するために、メモリを「使用」します。すべてのレコードをメモリ内の配列に格納するとスペースが必要になりますが、メモリアクセスはディスクアクセスよりもほぼ無限に高速であるため、クラスメートよりもはるかに高速に実行されます。

対照的に、クラスメートはハードディスクからオンデマンドでデータをロードするのを待つことでRAMを節約します。しかし、それは彼女にコストをかけることになります。ハードディスクをヒットすることは、すでにメモリにあるデータをフェッチすることに比べて非常にコストのかかるプロセスであり、ユーザーが変更を加えるたびにこれを行うのに行き詰まります。プログラムを開始するのにかかる時間と、すでに開いているプログラムに切り替えるのにかかる時間を考えてみてください。

そして、そこにはトレードオフがあります。ここで自問する重要なことのいくつかは次のとおりです。

  1. (処理する一般的な構成の)データセットが大きすぎて(または大きくなりすぎて)、メモリに完全に収まりませんか?通常は小さなデータセットを処理している場合、コンピュータには、おそらくそれだけの価値がある十分なRAMが搭載されています。

  2. データにアクセスできるようになるには、どれくらいの速さが必要ですか?リアルタイムアクセスは重要ですか?オンデマンドでハードディスクからロードするのに時間がかかりすぎる、特に大規模または複雑なデータセットですか?ユーザーはどのようなパフォーマンスを期待していますか?

  3. アプリケーションはどのようなシステムを対象としていますか?組み込みシステムやその他の特殊なケースでは、独自の設計アプローチが必要になる場合があります。RAMが豊富で​​、固定ストレージの量が非常に限られている場合もあれば、まったく逆の場合もあります。標準の最新のPCハードウェアを使用している場合、ユーザーは何を望んでいるか、必要としているか、すでに持っていますか?ターゲットユーザーのほとんどがすでに比較的「ビーフィー」なハードウェアを使用している場合は、より多くの潜在的なオーディエンスをターゲットにする場合とは異なる設計上の決定を下す可能性があります。これらのトレードオフは、プログラムの表現されたシステムを通じて以前に明示されたものです。要件。

  4. 特別な状況を考慮に入れる必要がありますか?複数のユーザーによる同時アクセスのようなものは、すべてのデータをメモリに保持することをはるかに困難にします。他のユーザーは、ローカルコンピューターのメモリにのみ保存されているデータをどのように読み取ることができますか?ここでは、(おそらく共有サーバー上でも)共通ファイルを共有する必要があります。

  5. 他の部分よりも頻繁にアクセスされるデータの特定の部分はありますか?これらの特定の部分を常にメモリに保持し、残りを遅延ロードすることを検討してください(つまり、ユーザーがアクセスした場合にのみ、それらをメモリにフェッチしようとします)。

そして、その最後のポイントが示唆するように、バランスの取れた、または組み合わされたアプローチの何かは、おそらく「理想的な」解決策に到達するのとほぼ同じくらいです。アプリケーションのアイドル状態のときに、編集や変更をディスク上のファイルに定期的に書き戻しながら、できるだけ多くのデータをRAMに保存できます。平均的なプログラムは、その逆とは対照的に、ユーザーが何かをするのを待つのに多くの時間を費やします。これらのアイドル状態のCPUサイクルを利用して、目立った速度の低下を招くことなく、メモリに保持されているものをディスクにフラッシュして戻すことができます。このアプローチはソフトウェア開発で常に使用されており、EClaessonの回答で指摘された落とし穴を回避するのに役立ちます。アプリケーションがクラッシュしたり、予期せず終了したりした場合は、そのほとんどは、舞台裏ですでにディスクにコミットされています。

追記:もちろん、Dark Falconの答えは正しいです。本番アプリケーションでは、データベースのようなものを使用してデータを処理する可能性が高いということです。しかし、これは教育目的のように思われるため、各アプローチの背後にある基本的なトレードオフを理解することがはるかに重要だと思います。

于 2010-12-04T14:57:14.993 に答える
5

深刻なアプリケーションでは、優れたプログラマーはおそらく既存のライブラリを使用してデータを管理します。このツールの選択は、正確な要件によって異なります。

  1. 複数のユーザーが同時にアクセスする必要がありますか?
  2. 複数のマシンからアクセスする必要がありますか?

大量の情報を保存するための最も一般的な選択肢は、MySQL、Postgres、Microsoft SQL Server、SQLiteなどのSQLベースのデータベースです。これらは、ほとんどの場合、クラスメートのソリューションに似ています。

于 2010-12-04T14:33:37.247 に答える
2

お使いのバージョン(すべてのレコードをメモリに保持する)の方がおそらく高速です。ただし、レコード数が増える場合は、十分なメモリが必要です。これの悪い点は、プログラムがクラッシュしたり、終了が正しくなかったりすると、ファイルに保存されなかったため、すべてのデータが失われることです。

file ioは最速ではないため、クラスメートのバージョンはそれほど高速ではありません。ただし、必要なメモリが少なくて済み、ほとんどのデータがすでにファイルに含まれているため、クラッシュ時の安全性が高くなります。

于 2010-12-04T14:30:30.200 に答える
2

これは、実行するシステムの詳細、データセットのサイズ、および開発時間とCPU時間の相対的なコストを知らなければ答えられない質問です。システムに十分なメモリがある場合は、RAM内のコピーで作業することをお勧めします。非常に限られたRAM(今日は主に組み込みアプリケーションに見られる)のある小さなシステムでは、ディスクファイルを更新しなければならない場合があります。他に考慮すべきことは、実際にディスクに書き込む前にオペレーティングシステムが実行する可能性のあるバッファリング、プログラムがクラッシュした場合のファイルの整合性で何が起こるか、ディスクへの書き込みが非常に遅いか、ディスクへの書き込みが「高価」である場合でもです。書き込みサイクル数が制限されています(一部のフラッシュディスクテクノロジ)。

これが今日のデスクトップコンピューターでの小さな実用的な問題である場合は、小さなデータセットで実行するのにかかる可能性のある比較的わずかな時間に対して、さまざまなソリューションの開発に費やした時間を検討することもできます。

また、今日では、ファイルシステムに独自のデータベースを作成するよりも、関連する問題の処理に優れた既存のデータベースを使用して問題を解決する方がよい場合があります。

于 2010-12-04T14:35:18.570 に答える
1

レコードが固定サイズでない場合、適切な場所でのレコードの編集は微妙です。これは、バイナリ形式と、行を未使用としてマークするためのサポート(たとえば、外部インデックスまたはホワイトアウト)でのみ実際に可能です。ファイルシステムはアトミックではないため、実行した内容が完全にディスク上にあるかどうかを確認することはできません。

これにより、問題は他の学生用ノートアプリケーションよりもはるかに複雑になり、データベースに委任するのが最適です(SQLiteとTokyoCabinetはより軽量なものです)。データベースを使用できない場合は、単純な実装を使用してください。バグが少なくなり、データベースに置き換えるときに執着することはありません。したがって、メモリ内のファイル全体を読み取るというアプローチは、最良の選択のように思えます。

于 2010-12-04T17:37:54.260 に答える