ほとんど変更されない「合理的に大量の」データを保存する実用的な方法は?


13

事前に計算されたルックアップテーブルなどについて考えます。アプリケーションで値をハードコーディングする代わりにデータベースを使用する方が適切なのはどの時点ですか?値は変更されず、メンテナンス開発者からうまく分離されます。100個の値、1k、10k、100k?約4万の値を保存したいです。現時点では、これはマシン生成のswitchステートメントです(VS2010は不満です)。

編集:

誰かが好奇心があるなら、私はこれにどのようにアプローチしたのですか?私のデータは2つの100k要素のfloat配列に保存可能でしたので、それは私がやったことです。データを生成するのに約20秒かかりましたので、一度それを行い、BinaryFormatterを使用して埋め込みリソースにシリアル化しました。データの解凍には、アプリケーションの起動時に約5ミリ秒かかり、私が置き換えていたデータベース実装(これらのハードコードされた値は以前に保存されていた)をほぼ45,000倍上回ります。

回答:


5

私の提案は、データをファイルまたはデータベーステーブルに保持することです。速度が問題にならない場合は、実行時にファイルまたはデータベース(データベースの方が良い)を照会します。メモリに問題はないが、ある程度の速度が必要な場合は、プログラムの起動時にデータをメモリにロードします。C#では、ハッシュテーブルを配列、リスト、または(最適なオプション)として使用し、実行時に必要なデータを返すメソッド(つまり、getDataValue(string keyToValue))を使用できます。

メンテナンスが非常に難しく、exeフットプリントが大きくなるため、switchステートメントを使用しないことをお勧めします。

ハッシュテーブル(例:http : //support.microsoft.com/kb/309357


これが最終的に私がやったことです。更新された投稿を確認してください。
ブライアンベッチャー

1
データベースの提案に対して+1。データベースは、大量のデータを格納するために作成されており、非常に迅速に取得できます。
NoChance

stackoverflow.com/questions/301371 / ...を参照してください。ハッシュテーブルよりも辞書を使用するほうがよい理由について。YMMV
クリス・マッキー

6

個人的には、1つの特定の展開または修正プログラムのためにデータを微調整する必要がなくなるまで、アプリケーションにハードコードされた任意の量のデータを保存しても構いません。

ただし、C#switchステートメントを使用したデータの保存とアクセスは、データストレージモデルとデータアクセスモデルを密接に結合し、1つのメソッドアクセスメソッド(スイッチパラメーターによる)のみを意味するため、かなり悪い習慣です。

ハッシュテーブルまたはディクショナリにデータを保存し、データを取得するための個別のクラスを提供し、ルックアップディクショナリを1回作成することをお勧めします。

最近、ビジネスルール(SiteMapの流なインターフェイスまたはルール定義のための税計算機インタビュー質問チェック「calc」メソッド)を指定するために小さなDSLを実装し、これらのルールを照会するための個別のオブジェクトを提供するのがかなり便利であることがわかりました。この手法は、スイッチケースのシナリオに適しています。

このような分解の優れた利点の1つは、XXXk行blobに触れることなく、そのデータを定義する多数のビューをデータに実装できることです。


私はいくつかの例を使って答えを広げました。
ヴァレラコルパエフ

2

40kのline switchステートメントは少し疑問です。クエリ操作を実行する必要があると思いますか?データをカプセル化しようとしましたか?次に、LINQを使用してコレクションでクエリ操作を実行し、パフォーマンスをテストします。StopWatchなどのタイマーを使用して単体テストを実行することにより、具体的な時間を取得します。そして、あなたはそれがちょうどうまくいくかもしれないと思うなら。ユーザーにとってパフォーマンスが許容できるかどうかを確認します。


2

このような要件が2回ありました。アプリケーションは、データベースのセットアップ/アクセスが不要なスタンドアロンとして設計されました。どちらの場合も、XMLファイルを使用してデータを保存しました。2.0フレームワーク上にある最初のものでは、古いスタイルのXML解析呼び出しを使用してデータを検索しました。新しいフレームワークの3.5フレームワークでは、LINQ to XMLを使用して必要なものを見つけました。どちらの場合も、データへのアクセスはクラスにカプセル化されました。


1

ここで重要なことは、パブリックインターフェイスが実装をカプセル化することを確認することです。しかし、それはあなたの質問ではなく、そうではないと考える理由はありません。それ以外は、パフォーマンスと悲しみの問題にすぎません(パフォーマンスの違いは気にする価値がないかもしれません)。VS 2010の問題の実用的な解決策として、ケースステートメントをいつでもケースステートメントの階層に分割できます。トップレベルは、たとえば、それぞれ4000ケースのケースステートメントを持つ10のメソッドのいずれかを呼び出すことができます。必要に応じて、10個のファイルをそれぞれ独自のファイルに入れることができます。少しいですが、あなたはとにかくコードを生成しています。

DBに切り替える番号については、DBを使用しないことが問題になる場合に限ります。


私のインターフェースが実装をカプセル化しているという考えに感謝しています。この機能はGetValuesForInput-typeメソッドを介して公開され、私の大規模なステートメントは実装に隠されています。
ブライアンベッチャー

1

SQL Compactのようなものを使用できます。データをテーブルに入れ、DBファイルをプロジェクトに残します。テーブルは、switchステートメントよりもそのデータ量に適しています。


1

ここのキーワードは「ほとんど」ではないと思います

データ変更されない場合(たとえば、事前に計算された数学的な値、色定数など)、サイズが管理可能な限り、コード内に保持してください。パフォーマンスに問題がある場合、case / switchステートメントは他のオプションと比較して非常に遅いことに注意してください。

データがほとんど変更されない場合(電話の市外局番、国境など)、おそらく何らかの方法でデータを外部に保持することを検討するでしょう。特に、数十以上の値になり始めた場合。


1
それは、コンパイラがどれだけ優れているかによります。Delphiのcaseステートメントは非常に効率的です。
ローレンペクテル

1

大量のデータをアプリケーションに保存すると、プログラムの読み込みが遅くなり、バイナリまたは実行可能ファイルを使用できる場合にコードが危険にさらされる可能性があります。

また、プログラムが何度も編集されている場合、間違っているか、変更コマンドの結果として数字を誤って入力すると、エラーが発生する可能性があります。

将来、誰かがデータのクエリを実行するように要求する場合があります。たとえば、誰かが列の平均を要求する場合があります。で、すべての手順を実行して、コードを実稼働環境にプロモートします。これは本当に良くありません。

データが大きい場合は、特にデータとコードを分離することをお勧めします。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.