`stackalloc` キーワードの実際の使用法
-
16-09-2019 - |
質問
実際に使ったことのある人はいますか stackalloc
C# でプログラミングしているときは?何が機能するのかは知っていますが、コードにそれが現れるのは偶然だけです。入力を開始すると Intellisense がそれを提案するからです。 static
, 、 例えば。
利用シーンとは関係ありませんが、 stackalloc
, 、私は実際に自分のアプリでかなりの量のレガシー相互運用を行っているので、時々、次の使用に頼ることができます。 unsafe
コード。しかし、それにもかかわらず、私は通常、回避する方法を見つけます unsafe
完全に。
また、.Net の単一スレッドのスタック サイズは ~1Mb なので (間違っていたらごめんなさい)、私は使用することをさらに控えています。 stackalloc
.
実際に次のように言えるケースはありますか?「これは、私が危険にさらして使用するのにちょうど適した量のデータと処理です stackalloc
"?
解決
stackalloc
を使用する唯一の理由は、パフォーマンス(いずれかの計算又は相互運用のため)です。代わりに、ヒープ割り当てられた配列のstackalloc
を使用することにより、あなたは、あなたはそれが自動的に解放され、それがヒープ配列よりも割り当てることが高速です、配列を突き止める必要がありません(GCが少ない実行する必要がある)以下GC圧力を作成します方法出口(GC実行時にヒープに割り当てられた配列のみ割り当て解除されます)。また、代わりに(malloc関数または.NET同等のような)天然アロケータのstackalloc
を使用して、あなたはまた、スコープの終了時に速度および自動解除を得る。
パフォーマンス賢明なあなたがstackalloc
を使用している場合、あなたは大幅に起因するデータの局所性にCPUのキャッシュヒットのチャンスを増やします。
他のヒント
私は[近く]リアルタイムDSPの仕事のためにバッファを割り当てるstackallocを使用しています。これは、パフォーマンスができるだけ一致するように必要な非常に特殊なケースでした。一貫性と全体のスループットに差がある注 - このケースで私はプログラムのその時点でのガベージコレクションの非決定論と、ヒープ割り当てが遅すぎることを懸念しませんでした。私は、例99%でそれを使用することはありません。
stackalloc
は、安全でないコードにのみ関連しています。マネージコードのためには、データを割り当てるために場所を決定することはできません。 (彼らは、ヒープ上に割り当てられた場合に参照型の一部でない限り)値型は、デフォルト当たりスタック上に割り当てられています。参照型はヒープに割り当てられます。
プレーンバニラ.NETアプリケーションのデフォルトのスタックサイズは1MBですが、あなたはPEヘッダーにこれを変更することができます。あなたが明示的にスレッドを開始している場合は、コンストラクタのオーバーロードを経由して別のサイズを設定することができます。 ASP.NETアプリケーションでは、デフォルトのスタックサイズを使用すると、2つの環境間の切り替えしている場合は心に留めておくべきものである、唯一の256Kです。
スパンの Stackalloc 初期化。以前のバージョンの C# では、stackalloc の結果はポインター ローカル変数にのみ格納できました。C# 7.2 では、stackalloc を式の一部として使用し、スパンをターゲットにできるようになりました。これは、unsafe キーワードを使用せずに行うことができます。したがって、書く代わりに、
Span<byte> bytes;
unsafe
{
byte* tmp = stackalloc byte[length];
bytes = new Span<byte>(tmp, length);
}
簡単に次のように書くことができます。
Span<byte> bytes = stackalloc byte[length];
これは、操作を実行するためにある程度のスクラッチ領域が必要だが、比較的小さいサイズにヒープ メモリを割り当てることは避けたいという状況でも非常に役立ちます。
Span<byte> bytes = length <= 128 ? stackalloc byte[length] : new byte[length];
... // Code that operates on the Span<byte>