C#/。ネットでは、動的タイプはオブジェクトよりも少ないスペースをとっていますか?

StackOverflow https://stackoverflow.com/questions/4823213

質問

ユーザーが処理する変数を指定できるコンソールアプリケーションがあります。これらの変数には、ストリング、ダブルとロングの3つのフレーバーがあります(ダブルとロングは、最も一般的に使用されるタイプです)。ユーザーは、好きな変数を指定して、どんな順序でも指定できます。これにより、私のシステムはそれを処理できる必要があります。この目的のために、私のアプリケーションでは、これらをオブジェクトとして保存し、必要に応じて鋳造/cast/casting consing/casting/casting onsing/casting/casting onsing/casting onsing/oncastingでした。例えば:

public class UnitResponse
{
    public object Value { get; set; }
}

私の理解では、箱入りのオブジェクトは標準の値タイプよりも少し多くのメモリ(約12バイト)を占有することでした。

私の質問は、動的キーワードを使用してこれらの値を保存する方が効率的ですか?ボクシング/ボクシングの問題を回避する可能性があり、それがより効率的であれば、このパフォーマンスにどのように影響しますか?

編集

何らかのコンテキストを提供し、「これについて心配するのに十分なRAMを使用していると確信していますか」と私の最悪の場合、私は心配する420,000,000のデータポイント(60変数 * 7,000,000レコード)を持っています。これは、私が各変数(いくつかのブーチャンなどを含む)について保持する他のデータの束に加えています。したがって、メモリを減らすことには大きな影響があります。

役に立ちましたか?

解決

わかりました 本物 ここに質問「メモリに保存している膨大なデータセットがありますが、時間とメモリの両方の空間でそのパフォーマンスを最適化するにはどうすればよいですか?」

いくつかの考え:

  • あなたはボクシングを嫌い、恐れることは絶対に正しいです。ボクシングには大きなコストがあります。まず、はい、箱入りオブジェクトは余分なメモリを取り上げます。第二に、箱入りオブジェクトは、スタックやレジスタではなく、ヒープに保存されます。第三に、それらは収集されたゴミです。これらのオブジェクトのすべてをGCの時間に尋問する必要があります。これは、他のオブジェクトへの参照が含まれているかどうかを確認する必要がありますが、これは決してありません。これは、GCスレッドでは多くの時間です。ボクシングを避けるために何かをする必要があります。

ダイナミックではありません。それはボクシングに加えて、他の多くのオーバーヘッドです。 (C#のダイナミックは非常に高速です 他の動的ディスパッチシステムと比較してください, 、しかし、それは絶対的な観点からは高速でも小さいもありません)。

それはグロスですが、レイアウトがさまざまなフィールド間でメモリを共有する構造体を使用することを検討することができます - Cのユニオンのように 本当に本当にひどいまったく安全ではありません しかし、それはこのような状況で役立ちます。 「structlayoutattribute」のWeb検索を行います。チュートリアルがあります。

  • 長い、二重、または文字列、本当に? int、float、またはstringにすることはできませんか?データは本当に数十億を超える規模を超えているのか、それとも15桁まで正確ですか? intとfloatは99%のケースで仕事をしませんか?彼らは半分のサイズです。

通常、誤った経済であるため、FloatをDoubleで使用することはお勧めしません。 4バイトの節約が違いを生むように、人々は1つの数字を持っているときにこのように節約することがよくあります。 4200万のフロートと4200万のダブルの違いはかなりのものです。

  • データに規則性はありますか?たとえば、4,200万のレコードのうち、たとえば、各2倍の長い100000値、各文字列に100000値の実際の値は100000しかないと仮定します。その場合、ロング、ダブル、文字列のある種のインデックス付きストレージを作成し、各レコードが低ビットがインデックスである整数を取得し、上部2ビットはそれを取得するストレージを示します。これで、それぞれがINTを含む4,200万のレコードがあり、値はどこかでうまくコンパクトな形に保存されます。

  • ブーチャンをビットとしてバイトに保存します。ビットシフトを行うためにプロパティを作成して、出すようにします。そのようにいくつかのバイトを保存してください。

  • メモリは実際にはディスクスペースであることを忘れないでください。 RAMは、その上に便利なキャッシュです。データセットが大きすぎてRAMを維持できない場合、 なにか ディスクに戻ってページアウトし、後で読み戻します。それがあなたであるか、それがオペレーティングシステムである可能性があります。オペレーティングシステムよりも、データの局所性についてもっと知っている可能性があります。データを便利なページ可能な形式(Bツリーなど)でディスクに書き込み、ディスクに物を保持し、必要なときにメモリに持ち込むことをより効率的にすることができます。

他のヒント

ここで間違ったことを見ているかもしれないと思います。ダイナミックが何をするかを覚えておいてください。これ 実行時に、プロセスで再びコンパイラを起動します. 。コンパイラに数十万バイトのコードをロードし、すべてのコールサイトで、各動的操作の新たに放出されるILの結果を含むキャッシュを放出します。 8を節約するために数十万バイトを費やしています。それは悪い考えのようです。

そしてもちろん、あなたは何も保存しません。 「ダイナミック」は、派手な帽子をかぶった「オブジェクト」です。 「ダイナミック」オブジェクトはまだ箱入りです。

いいえ。 dynamic と関係しています オブジェクトの操作の実行方法, 、オブジェクト自体の保存方法ではありません。この特定のコンテキストでは、値タイプはまだ箱入りです。

また、この努力はすべて、オブジェクトごとに12バイトの価値がありますか?確かに、あなたの時間をいくつかのキロバイト(もしそうなら)を節約するよりも良い使用がありますか?プログラムによるRAMの使用が実際に問題であることを証明しましたか?

いいえ。ダイナミックは、単にオブジェクトとして保存します。

これは、ほとんどまたはまったく利益をもたらさないミクロの最適化である可能性があります。これが実際に問題になった場合、物事をスピードアップするために使用できる他のメカニズム(ジェネリック)があります。

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