ページへ戻る
印刷
技術系備忘録/C++/最適化小手先テクニック/ビットフィールドを活用すべし(メモリ節約編)
をテンプレートにして作成 ::
シンクリッジ
xpwiki
:技術系備忘録/C++/最適化小手先テクニック/ビットフィールドを活用すべし(メモリ節約編) をテンプレートにして作成
開始行:
例えば、文庫本を管理するソフトウェアを作るとします。
各文庫本にはジャンル情報があり、ジャンルは複数個持つこと...
何も考えずに組むと List1 のようなクラスになると思います。
-List1
#prettify{{
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)は置いといて、ジャンル情報に...
ジャンル情報を見ると、各項目はフラグ(true or false)として...
それが6種類あるので、使用するメモリは、4Byte×6で24Byteで...
文庫本が数冊であれば問題ない量ですが、数十万冊などもあり...
少し工夫して、int ではなく bool を使うようにしたものが Li...
-List2
#prettify{{
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 に収まりました。(b...
これで十分かもしれませんが、もっと節約したい場合もあると...
ビットフィールドを使うと以下のようになります。
-List3
#prettify{{
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で収まります。
さらに、例では6ジャンルしか定義してませんが、8ジャンルま...
以上、ビットフィールドの活用方法としては一番単純な例です...
なお、C(C++)言語の通説として、「コンピュータにとってはint...
実際の運用では、この場合はCBookを構築、比較、コピーなどの...
特に昨今のコンピュータは、メモリはCPUより遅いクロックで動...
/*
余談ですが、Pentium3とかが出始めた頃、ちょっと時間のかか...
*/
ちなみに、ビットフィールドを使用しないで同じことをやる例...
-list4
#prettify{{
#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
#prettify{{
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;
};
}}
このように、記述することが可能です。
面倒なビット演算はコンパイラが面倒みてくれますので、nSize...
-
#prettify{{
if( m_Book.m_Property.nSize == 2 ){ // A5サイズなら
}}
みたいな記述も可能です。
(ただ、内部的にはビット演算処理を行うコードが出力されて...
こうなると List4 にある #define を使って自前で処理をコー...
以上、今回のネタはメモリ節約という最適化の一つのネタとし...
ただ、メモリ節約と処理速度との関係は難しく、メモリ節約す...
クラスの実装の際、そのクラスの使われ方を考慮しコーディン...
終了行:
例えば、文庫本を管理するソフトウェアを作るとします。
各文庫本にはジャンル情報があり、ジャンルは複数個持つこと...
何も考えずに組むと List1 のようなクラスになると思います。
-List1
#prettify{{
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)は置いといて、ジャンル情報に...
ジャンル情報を見ると、各項目はフラグ(true or false)として...
それが6種類あるので、使用するメモリは、4Byte×6で24Byteで...
文庫本が数冊であれば問題ない量ですが、数十万冊などもあり...
少し工夫して、int ではなく bool を使うようにしたものが Li...
-List2
#prettify{{
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 に収まりました。(b...
これで十分かもしれませんが、もっと節約したい場合もあると...
ビットフィールドを使うと以下のようになります。
-List3
#prettify{{
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で収まります。
さらに、例では6ジャンルしか定義してませんが、8ジャンルま...
以上、ビットフィールドの活用方法としては一番単純な例です...
なお、C(C++)言語の通説として、「コンピュータにとってはint...
実際の運用では、この場合はCBookを構築、比較、コピーなどの...
特に昨今のコンピュータは、メモリはCPUより遅いクロックで動...
/*
余談ですが、Pentium3とかが出始めた頃、ちょっと時間のかか...
*/
ちなみに、ビットフィールドを使用しないで同じことをやる例...
-list4
#prettify{{
#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
#prettify{{
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;
};
}}
このように、記述することが可能です。
面倒なビット演算はコンパイラが面倒みてくれますので、nSize...
-
#prettify{{
if( m_Book.m_Property.nSize == 2 ){ // A5サイズなら
}}
みたいな記述も可能です。
(ただ、内部的にはビット演算処理を行うコードが出力されて...
こうなると List4 にある #define を使って自前で処理をコー...
以上、今回のネタはメモリ節約という最適化の一つのネタとし...
ただ、メモリ節約と処理速度との関係は難しく、メモリ節約す...
クラスの実装の際、そのクラスの使われ方を考慮しコーディン...
ページ名: