質問

ファイルの読み取りと書き込みを含むプログラムを作成するのは初めてです。実際、私はこれを行うのに最適なテクニックは何だろうと思っています。私の仕事をクラスメートと比較すると、私たちの論理は互いに大きく異なるためです。

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

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

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

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

役に立ちましたか?

解決

これは、プログラミングで何度も何度も遭遇する古典的なケースです。速度やメモリの使用について最適化しますか?

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

すべてのレコードをメモリにロードするソリューションにより、実行時に各レコードにアクセスして修正するためにメモリを「支出」します。メモリ内のすべてのレコードを保存すると、メモリアクセスがディスクアクセスよりもほぼ無限に高速であるため、アプローチはクラスメートよりもはるかに速く実行されます。

対照的に、クラスメートは、ハードディスクから需要のあるデータをロードするのを待つことでRAMを節約します。しかし、それは彼女にコストがかかるでしょう:ハードディスクを打つことは、すでに記憶にあるデータを取得するのと比較して、ひどく高価なプロセスであり、彼女はこれをしていると思います ユーザーが変更するたびに. 。プログラムを開始するのにかかる時間と、すでに開いているプログラムに切り替えるのにかかる時間を考えてください。

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

  1. データセット(対処する一般的な構成)は、メモリに完全に収まるには大きすぎる(または大きくなりすぎます)?通常、小さなデータセットを扱っている場合、コンピューターはおそらく価値があるほど十分なラムを持っています。

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

  3. アプリケーションはどのようなシステムをターゲットにしていますか?埋め込まれたシステムやその他の特別なケースが、独自のデザインアプローチを必要とする場合があります。豊富なRAMと非常に限られた量の固定ストレージがあるかもしれませんし、まったく反対のものがあるかもしれません。標準の最新のPCハードウェアを使用している場合、ユーザーは何を望んでいる/必要/既に持っていますか?ターゲットユーザーのほとんどが既に比較的「ビーフ」ハードウェアを使用している場合、より大きな潜在的な視聴者をターゲットにすることを目指している場合とは異なる設計上の決定を下す可能性があります。プログラムの表現システムを通じて明示的になっているこれらのトレードオフが確実に見られました。要件。

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

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

そして、その最後のポイントがヒントするにつれて、バランスの取れたアプローチまたは結合されたアプローチのようなものは、おそらく「理想的な」ソリューションに到達するのとほぼ同じでしょう。できるだけ多くのデータをRAMに保存することができますが、アプリケーションのアイドル状態中に編集または変更をディスク上のファイルに定期的に書き込みます。平均的なプログラムが、他の方法とは対照的に、ユーザーが何かをするのを待つのに費やす時間がたくさんあります。これらのアイドル状態のCPUサイクルを利用して、顕著な速度ペナルティを発生させることなく、メモリに保持されているものをディスクに戻します。このアプローチは、ソフトウェア開発で常に使用されており、Eclaessonの答えによって指摘されている落とし穴を回避するのに役立ちます。アプリケーションがクラッシュしたり、予期せずに終了した場合、データのごくわずかな部分のみが失われる可能性が高いため、 多くの その舞台裏のディスクにすでにコミットしていました。

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

他のヒント

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

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

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

バージョン(すべてのレコードをメモリに保持する)は、おそらくより高速になります。ただし、レコードカウントが成長した場合、十分なメモリが必要です。これで悪いことは、プログラムのクラッシュまたは不正な出口により、ファイルに保存されなかったため、すべてのデータを失うことです。

ファイルIOはあなたができる最速ではないため、クラスメートのバージョンはそれほど速くありません。ただし、ほとんどのデータがすでにファイルにあるため、メモリが少なくなり、クラッシュでより安全になります。

これは、実行するシステムの詳細、データセットのサイズ、および開発時間とCPU時間の相対コストを知らずに回答できない質問です。システムに十分なメモリがある場合、RAMのコピーに取り組むことがおそらく望ましいです。 RAMが非常に限られている小さなシステム(現在は、主に埋め込みアプリケーションで見つかっています)では、ディスクファイルを更新する必要がある場合があります。考えるべきその他のことは、ディスクに実際の書き込みの前にオペレーティングシステムが行う可能性のあるバッファリング、プログラムがクラッシュした場合にファイルの一貫性で起こること、およびディスクへの書き込みが本当に遅いため、または本当に遅いために「高価」であっても、書き込みサイクルの数は限られています(いくつかのフラッシュディスクテクノロジー)。

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

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

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

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

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top