boost::dynamic_bitset concat performance
boost::dynamic_bitset concat performance
我想用一种不会影响性能的方式将一个大的bitset和一个小的bitset连接起来。目前,我的应用程序在以下代码中花费了20%的cpu时间:
boost::dynamic_bitset<> encode(const std::vector<char>& data)
{
boost::dynamic_bitset<> result;
std::for_each(data.begin(), data.end(), [&](unsigned char symbol)
{
for(size_t n = 0; n < codes_[symbol].size(); ++n)
result.push_back(codes_[symbol][n]); // codes_[symbol][n].size() avarage ~5 bits
});
return result;
}
我读了这篇文章,提出了一个解决方案,不幸的是,这对我不起作用,因为目标bitset和源bitset的大小差异非常大。
任何想法?
如果这是不可能有效地做boost::dynamic_bitset那么我开放的其他建议。
这是因为您一直在使用push_back()
,但实际上,您已经提前知道了大小。这意味着大量的冗余复制和重新分配。你应该先调整一下大小。此外,您不必对每个值进行push_back()
-您应该可以使用某种形式的insert()
(我实际上不知道它的确切接口,但我认为append()
是名称)一次插入整个目标向量,这应该明显更好。
此外,您将dynamic_bitset
保留为unsigned long,但据我所知,您实际上只是将unsigned char
插入其中。改变这一点会让你的生活更轻松。
我也很好奇codes_
是什么类型-如果它是map
,你可以用vector
替换它,或者事实上,因为它是静态的最大大小(256个条目是unsigned char
的最大值),一个静态数组。
我之前尝试过在性能代码中使用boost bitset,但很失望。我深入研究了一下,得出结论,我最好实现我自己的位缓冲类,尽管我忘记了让我确信boost的类永远不会很快的细节(我确实检查了产生的程序集)。
我仍然不知道构建位缓冲区/位集/位流或任何你想叫它们的最快方法是什么。一个同事正试图找出这个相关的问题,但在撰写本文时,它仍在等待一个好的答案。
我写了自己的bitset类。我感谢任何改进的建议。我会试着去看看上交所,看看那里是否有什么有用的东西。
使用我的非常粗略的基准测试,我在每次附加6位的情况下获得了11倍的性能提升。
class fast_bitset
{
public:
typedef unsigned long block_type;
static const size_t bits_per_block = sizeof(block_type)*8;
fast_bitset()
: is_open_(true)
, blocks_(1)
, space_(blocks_.size()*bits_per_block){}
void append(const fast_bitset& other)
{
assert(!other.is_open_);
for(size_t n = 0; n < other.blocks_.size()-1; ++n)
append(other.blocks_[n], bits_per_block);
append(other.blocks_.back() >> other.space_, bits_per_block - other.space_);
}
void append(block_type value, size_t n_bits)
{
assert(is_open_);
assert(n_bits < bits_per_block);
if(space_ < n_bits)
{
blocks_.back() = blocks_.back() << space_;
blocks_.back() = blocks_.back() | (value >> (n_bits - space_));
blocks_.push_back(value);
space_ = bits_per_block - (n_bits - space_);
}
else
{
blocks_.back() = blocks_.back() << n_bits;
blocks_.back() = blocks_.back() | value;
space_ -= n_bits;
}
}
void push_back(bool bit)
{
append(bit, 1);
}
bool operator[](size_t index) const
{
assert(!is_open_);
static const size_t high_bit = 1 << (bits_per_block-1);
const size_t block_index = index / bits_per_block;
const size_t bit_index = index % bits_per_block;
const size_t bit_mask = high_bit >> bit_index;
return blocks_[block_index] & bit_mask;
}
void close()
{
blocks_.back() = blocks_.back() << space_;
is_open_ = false;
}
size_t size() const
{
return blocks_.size()*bits_per_block-space_;
}
const std::vector<block_type>& blocks() const {return blocks_;}
class reader
{
public:
reader(const fast_bitset& bitset)
: bitset_(bitset)
, index_(0)
, size_(bitset.size()){}
bool next_bit(){return bitset_[index_++];}
bool eof() const{return index_ >= size_;}
private:
const fast_bitset& bitset_;
size_t index_;
size_t size_;
};
private:
bool is_open_;
std::vector<block_type> blocks_;
size_t space_;
};
- C++, printf vs cout performance
- C++:没有匹配调用'(concat) (std::string&)'
- char concat c++ 没有库函数
- Performance of C++ std::unordered_map vs Kotlin/Java HashMap
- C++ performance std::array vs std::vector
- OpenGL Performance
- c++ realloc performance vs malloc
- C :与宏定义的字符串Concat Constant String
- String & String::Concat(const char Str[])
- std::map performance c++
- Performance in CUDA
- const int&performance 问题
- Nsight or other Direct3D debbuger/performance analyser for V
- Performance: NaCl vs Emscripten
- Concat用于预定义的宏
- C++ concat const char with char
- std::vector vs std::array performance
- EASTL performance
- concat中的可变模板和推断的返回类型
- boost::dynamic_bitset concat performance