簡體   English   中英

std :: map <>或std :: vector <>處理大量標志時?

[英]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::vectorstd::map會更好嗎? 還是可能std::set更好? (我還沒有使用過std :: set ...)

std::setstd::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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM