1

ボクシングは多くの情報が利用できる人気のある概念であることを私は知っていますが、私は実際に答えを見つけることができないいくつかの質問があります:

1)ボックス化によって値型(構造体)がオブジェクト(参照型)または参照型に変換される場合、ボックス化されてパフォーマンスが低下する値型を使用するのはなぜですか?私は、構造体またはクラスの特定の場合の利点と適合性を認識しています。(1)値(値型)は一時ストレージスペースのスタックに存在する傾向があると言われていますが、どのくらいの期間ですか?タイプが必要ない場合、その時点で確実に処理および廃棄するにはどうすればよいですか?それとも、これが使い捨てパターンの出番です。構造体を使用する理由は、その利点によるものだと思います。

興味深いことに、構造体を使用して2つの文字列とDateTimeフィールドを格納すると、構造体は2つの参照(文字列)とDateTimeを一緒に保持します。明らかに、これは値が分散するよりも速いと思います。このデザインで知っておくべきことはありますか?(2)。

1)http://en.csharp-online.net/Classes、Structs、and Objects—Boxing and Unboxing

2)http://dotnetperls.com/Content/Struct-Examples.aspx

私はここで私が求めている答えを検索しましたが、運がありません。学び、共有するための多くの知恵があるので、私は通常、GC、ジェネリック、例外処理などのトピックをこのサイトで検索します。

すべてのポスターへの(潜在的な)教育に感謝します!潜在的なナイーブを許してください。内部を学ぶことで、ILなどの理解に時間を費やすことができます(すぐに取り組むべきことがあります)。

4

4 に答える 4

4

値の型を参照変数に渡さないと、ボックス化は行われません。わからないときは、次の質問に答えてください。

  • プリミティブ型のように振る舞います。
  • インスタンス サイズが 16 バイト未満であること。
  • 不変です。
  • 値のセマンティクスが望ましい。

私は通常、そのような変数の寿命も考慮します。メソッド内で使用されるローカル変数の場合は、構造体 (それ以外の場合はクラス) を使用します。

于 2009-03-06T22:36:50.537 に答える
1

他に考慮すべき点がいくつかあります -

まず、構造体が (一般的に) 不変であることを確認します。このため、参照型を含む構造体を持たないことは経験則として適切です。文字列は C# では不変であるため、これの例外になる可能性がありますが、設計の一般的な経験則という点では、これには注意が必要です。

第 2 に、これまで言及されていなかった構造体の別の使用例があります - 多数の小さなオブジェクトです。小さなオブジェクトの大きなリストまたは配列がある場合、構造体は劇的に優れたキャッシュの一貫性を提供し、絶対に重要です。これが、ほとんどの 3D エンジンがポイント/ベクトルに構造体を使用する理由です。それらは、頂点などにポイントの大きな配列を持つ傾向があります。

パフォーマンスがアプリケーションの重要な部分である場合、これは注意を払う価値のあることです。たとえば、私のアプリの 1 つで、単一の型をクラスから構造体に変更すると、長時間実行される (実行時間が 5 分を超える) プロセスが 40% 削減されました。大量の数学計算でオブジェクトを繰り返し使用している場合、オブジェクトをメモリ内で近くに配置すると、大きな利点が得られます。

今-あなたの場合、2つの文字列とDateTimeを使用しても、おそらくこれによる改善は見られません. 文字列で機能するタイプのルーチンは、おそらく重い計算を (できれば) 実行していません。つまり、空間内の 50 万点を変換したり、大規模な行列の解法を実行したりします。

最後に、.net3.5sp1 によって構造体がより便利になったことに気付くでしょう。3.5sp1 (x86) より前は、構造体呼び出しによるメソッドのインライン化はありませんでした。これにより、構造体によるパフォーマンスの向上が制限されていました。フレームワークを更新すると、古い構造体コードが大幅に高速化されます (場合によっては)。

于 2009-03-07T02:10:55.233 に答える
1

パフォーマンスの向上ではなく、論理的な利点のために値型を使用する必要があります。ただし、値型はスタック上で管理されるため、ガベージ コレクションに参加する必要はありません。常に作成および破棄される型 (int、float、double など) がある場合は、これらを構造体に変換することで効果を高めることができます。注意すべきことは、構造体を不変にすることもできる場合にのみ、これを実際に考慮する必要があるということです。

于 2009-03-06T22:35:59.917 に答える
0

常にボクシングが必要なわけではなく、ジェネリックではその必要はほとんどありません。
値型 (構造体は値型です) によって使用されるメモリは
、メソッドが終了/戻るとすぐに要求され、
それを行うために何もする必要はありません。 インスタンス メンバーとして宣言された値型は、オブジェクトが GC によって削除される

までメモリ内に存在します。 参照型はマネージド ヒープに保持されます。 メソッド内でインスタンス化された参照型は、それへの参照を保持しているオブジェクトがない場合、ガベージ コレクター によって削除されます。





GC は単独で動作するため、ほとんどの場合、そのままにしておく必要があります。
オブジェクトが GC によって削除される時期を予測することはできません。


Dispose パターンは参照型で使用されますが、GC にオブジェクトの削除を強制しません。通常、管理されていないリソースを解放するために使用されます。

スタック内の値については、次のことを考慮してください。 以下
のように、3 つのメソッドを持つ単純なプログラムがあるとします。
このプログラムが実行されると、Main メソッドが実行されます。
以下の番号に従ってください。


Main
{
   // (0) Stack is empty
   int firstInt = 0;
   // (1) Stack now contains:
   //                     firstInt
   DoSomething1();
   // (7) Stack still contains:
   //                     firstInt
}
// Program ends

DoSomething()
{
   int anInteger = 0; 
   // (2) Stack now contains:
   //                    anInteger
   //                    firstInt
   DoMore()
   // (5) Stack now contains:
   //                     anInteger
   //                     firstInt
}
// (6) anInteger goes out of scope

DoMore
{
  int anotherInteger = 1; 
   // (3) Stack now contains:
   //                     anotherInteger
   //                     anInteger
   //                     firstInt
}
// (4) anotherInteger goes out of scope

于 2009-03-06T23:23:15.637 に答える