ビットフィールドを活用すべし(メモリ節約編) |
例えば、文庫本を管理するソフトウェアを作るとします。 |
List1 |
class CBook // 文庫本クラス { public: string m_sTitle; // タイトル // ジャンルフラグ int m_nGenreScienceFiction; // SF (true or false) int m_nGenreLoveStory; // 恋愛 (true or false) int m_nGenreMystery; // ミステリー (true or false) int m_nGenreHorror; // ホラー (true or false) int m_nGenreComedy; // コメディ (true or false) int m_nGenreShort; // 短編 (true or false ) }; /* Windowsプログラムでは"int"を使わずに"BOOL"と書くことがあると思いますが、 "BOOL"は"int"の別名と定義されてますので、ここでは同じ意味と思って下さい。 */ |
ここでは、タイトル(m_sTitle)は置いといて、ジャンル情報に着目します。 |
List2 |
class CBook // 文庫本クラス { public: string m_sTitle; // タイトル // ジャンルフラグ bool m_bGenreScienceFiction; // SF (true or false) bool m_bGenreLoveStory; // 恋愛 (true or false) bool m_bGenreMystery; // ミステリー (true or false) bool m_bGenreHorror; // ホラー (true or false) bool m_bGenreComedy; // コメディ (true or false) bool m_bGenreShort; // 短編 (true or false) }; |
こうすることで、24Byteだったのが 6Byte に収まりました。(boolは1byteとしています) |
List3 |
class CBook // 文庫本クラス { public: string m_sTitle; // タイトル union{ // ジャンルフラグ struct{ char bScienceFiction : 1; // SF (true or false) char bLoveStory : 1; // 恋愛 (true or false) char bMystery : 1; // ミステリー (true or false) char bHorror : 1; // ホラー (true or false) char bComedy : 1; // コメディ (true or false) char bShort : 1; // 短編 (true or false) }; char All; }m_Genre; }; |
こうするとジャンル情報は1byteで収まります。 |
list4 |
#define SCIENCEFICTION 0x1 // SF #define LOVESTORY 0x2 // 恋愛 #define MYSTERY 0x4 // ミステリー #define HORROR 0x8 // ホラー #define COMEDY 0x10 // コメディ #define SHORT 0x20 // 短編 class CBook // 文庫本クラス { public: string m_sTitle; // タイトル char m_cGenre; // ジャンルフラグ }; |
このような記述は古いソフトウェアで良く見かけます。 数値型変数のビット管理をプログラマが自分で行うやり方です。 自分の場合(この例では)ビットフィールドを使うと思いますが、最適化の観点からみると、この記述で非効率となる要因は特に思いつきません。 逆に、コンパイラ任せにしないという意味から言えば、効率的な記述と言えるのかもしれません。 なお、ビットフィールドは 1BIT 単位でしか使えないものではありません。 例えば、CBook クラスに、本のサイズという項目を設けた場合は List5 のように記述出来ます。 |
List5 |
class CBook // 文庫本クラス { public: string m_sTitle; // タイトル union{ // フラグ struct{ // ジャンルフラグ char bScienceFiction : 1; // SF (true or false) char bLoveStory : 1; // 恋愛 (true or false) char bMystery : 1; // ミステリー (true or false) char bHorror : 1; // ホラー (true or false) char bComedy : 1; // コメディ (true or false) char bShort : 1; // 短編 (true or false) // 本のサイズ char nSize : 2; // 0=A3以上 1=A4 2=A5 3=A6 }; char All; }m_Property; }; |
このように、記述することが可能です。 |
前のページ try 〜 throw 〜 catch の乱用を避けるべし |
コンテンツのトップ |
次のページ シフト演算の乗除算に注意すべし |