30

1 つまたは複数の true/false 状態にある可能性のあるオブジェクトがある場合、プログラマーが複数のブール値を使用するだけでなく、フラグとビットマスクを頻繁に使用する理由について、私は常に少し曖昧でした。

それは .NET フレームワーク全体にあります。これが最良の例かどうかはわかりませんが、.NET フレームワークには次のものがあります。

public enum AnchorStyles
{
    None = 0,
    Top = 1,
    Bottom = 2,
    Left = 4,
    Right = 8
}

したがって、アンカー スタイルが与えられた場合、ビットマスクを使用して、どの状態が選択されているかを把握できます。ただし、可能な値ごとに定義された bool プロパティ、または個々の列挙値の配列を持つ AnchorStyle クラス/構造体を使用して、同じことを達成できるようです。

もちろん、私の質問の主な理由は、自分のコードで同様の慣行に従うべきかどうか疑問に思っているからです。

では、なぜこのアプローチを使用するのでしょうか。

  • メモリ消費が少ない?(ブールの配列/構造体よりも消費量が少ないようには見えません)
  • 構造体や配列よりも優れたスタック/ヒープ パフォーマンス?
  • 比較操作の高速化 価値の付加/除去の高速化?
  • それを書いた開発者にとってより便利ですか?
4

11 に答える 11

24

これは従来、メモリ使用量を削減する方法でした。だから、はい、C#ではかなり時代遅れです:-)

プログラミング手法としては、今日のシステムでは時代遅れになっている可能性があり、ブール値の配列を使用しても問題ありませんが...

ビットマスクとして格納された値を比較するのは高速です。AND および OR 論理演算子を使用して、結果の 2 つの int を比較します。

使用するメモリがかなり少なくなります。サンプル値の 4 つすべてをビットマスクに入れると、半バイトが使用されます。ブール値の配列を使用すると、ほとんどの場合、配列オブジェクトに数バイトと各ブール値に長いワードが使用されます。100 万個の値を格納する必要がある場合、ビットマスク バージョンが優れている理由が正確にわかります。

管理が簡単で、単一の整数値を処理するだけで済みますが、ブール値の配列はデータベースなどにまったく異なる方法で格納されます。

また、メモリ レイアウトにより、あらゆる面で配列よりもはるかに高速です。単一の 32 ビット整数を使用する場合とほぼ同じ速度です。これは、データの操作で得られる速度と同じくらい速いことは誰もが知っています。

于 2009-09-10T17:21:19.950 に答える
12
  • 複数のフラグを任意の順序で簡単に設定できます。

  • 簡単に保存して、データベースに 0101011 のシリーズを取得します。

于 2009-09-10T17:16:44.807 に答える
8

特に、新しいブール値をクラスに追加するよりも、新しいビットの意味をビットフィールドに追加する方が簡単です。一連のブール値よりも、あるインスタンスから別のインスタンスにビットフィールドをコピーする方が簡単です。

于 2009-09-10T17:17:28.797 に答える
6

また、メソッドをより明確にすることもできます。10 個のブール値と 1 個のビットマスクを持つメソッドを想像してください。

于 2009-09-10T17:23:10.547 に答える
3

実際、主に列挙型がバイトから派生している場合は、パフォーマンスが向上する可能性があります。その極端なケースでは、各列挙値は 256 までのすべての組み合わせを含むバイトで表されます。ブール値との可能な組み合わせが非常に多くなると、256 バイトになります。

しかし、それでも、それが本当の理由だとは思いません。私がそれらを好む理由は、C# がこれらの列挙型を処理する能力を与えてくれるからです。1 つの式で複数の値を追加できます。それらも削除できます。列挙型を使用して、1 つの式で一度に複数の値を比較することもできます。ブール値を使用すると、コードをより冗長にすることができます。

于 2009-09-10T17:19:22.637 に答える
2

かなり深刻なメモリ制限 (可能性は低い) を扱っている場合を除き、enum フラグを使用しないことをお勧めします。メンテナンス用に最適化されたコードを常に記述する必要があります。

複数のブール型プロパティを使用すると、コードの読み取りと理解、値の変更、Intellisense コメントの提供が容易になり、バグの可能性が減ることは言うまでもありません。必要に応じて、常に enum フラグ フィールドを内部で使用できますが、ブール値のプロパティで値の設定/取得を公開していることを確認してください。

于 2009-09-10T17:23:56.270 に答える
2

Raymond Chen は、このテーマに関するブログ投稿を行っています

確かに、ビットフィールドはデータ メモリを節約しますが、コード サイズ、デバッグ可能性、およびマルチスレッドの削減というコストとのバランスを取る必要があります。

他の人が言ったように、その時代はほとんど過去のものです。少しいじるのは楽しくてクールに見えるので、今でもやりたくなりますが、もはや効率的ではなく、メンテナンスの点で深刻な欠点があり、データベースとうまく連携しません。組み込みの世界、十分なメモリがあります。

于 2009-09-10T17:24:26.083 に答える
0

それはスピードと効率のためです。基本的に、作業しているのは単一の int だけです。

if ((flags & AnchorStyles.Top) == AnchorStyles.Top)
{
    //Do stuff
} 
于 2009-09-10T17:16:04.870 に答える