[英]std::map<> or std::vector<> when dealing with large sets of flags?
我正在使用編譯器,並且有大量的標志。 在大多數情況下,我的節點將收到很少的標志(最大的大約12個),但是標志的總數卻很大(超過50個。)所有標志都是枚舉中定義的整數:
enum flags_t
{
FLAG_ONE,
FLAG_TWO,
FLAG_THREE,
[...]
MAX_FLAG
};
我認為使用std::map<flags_t, bool>
更有意義,因為我的大多數節點都可能使用0、1或2個標志,並且節點的數量確實很大(很容易變成萬分之一)
// with a map we have to check the existing on a get to avoid creating
// useless entries in the map
bool node::get_flag(flags_t const f)
{
flag_iterator it(f_flags.find(f));
return it == f_flags.end() ? false : *it;
}
void node::set_flag(flags_t const f, bool const value)
{
f_flags[f] = value;
}
但是我想知道std::vector<bool>
是否最終不會更有效? 雖然乍看之下看起來不錯:
bool node::get_flag(flags_t const f)
{
return f_flags[f];
}
void node::set_flag(flags_t const f, bool const value)
{
f_flags[f] = value;
}
必須在初始化時分配向量(即,適當調整大小),或者get_flag()函數需要測試f是否為向量的一部分:
bool node::get_flag(flags_t const f)
{
return f >= f_flags.size() ? false : f_flags[f];
}
我可以通過resize()調用看到的問題是,即使我們最終從未真正使用過向量(大多數節點不需要任何標志!),我們也將一直分配/釋放內存(因此,在測試限制時)進行獲取可能是一個不錯的權衡,但我們還需要確保向量在set_flag()調用中足夠大...(在這種情況下,我們可能會立即分配整個標志集,以避免重新分配。)
bool node::set_flag(flags_t const f, bool const value)
{
if(MAX_FLAG > f_flags.size())
{
f_flags.resize(MAX_FLAG);
}
f_flags[f] = value;
}
那么... std::vector
或std::map
會更好嗎? 還是可能std::set
更好? (我還沒有使用過std :: set ...)
std::set
和std::map
都是標志的次佳選擇,因為它們動態分配存儲空間,從而導致不必要的碎片。
表示標志的一種簡單方法是將它們存儲為整數類型。 無符號的64位類型將為64個標志提供空間。 這將既節省空間又節省CPU,並且會啟動慣用的C ++。 例如:
enum flag_code
{
FLAG_ONE = 1ULL << 0,
FLAG_TWO = 1ULL << 1,
FLAG_THREE = 1ULL << 2,
[...]
};
typedef uint64_t flags_t;
void node::set_flag(flag_code f, bool value)
{
if (value)
f_flags |= f;
else
f_flags &= ~f;
}
bool node::get_flag(flag_code f)
{
return bool(f_flags & f);
}
如果需要超過64個標志,則最好用std::bitset
表示位操作,該操作還提供對基礎值的各個位的類似數組的訪問:
enum flag_code
{
FLAG_ONE,
FLAG_TWO,
FLAG_THREE,
[...]
MAX_FLAG
};
typedef std::bitset<MAX_FLAG - 1> flags_t;
void node::set_flag(flag_code f, bool value)
{
f_flags[f] = value;
}
bool node::get_flag(flag_code f)
{
return f_flags[f];
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.