我最近遇到了bitset模板,并且非常想在我当前的项目中使用它们.继续阅读,我发现std::bitset模板必须具有在编译时确定的大小.许多人建议使用它boost::dynamic_bitset来缓解这一要求.
比较两个,我决定做的速度比较set,flip和count方法.
结果很奇怪......我想知道是否有人可以为我阐明它.
代码在帖子的末尾,但我会解释我在这里做的事情.我有一个std::bitset对象(称之为bs)和一个boost::dynamic_bitset对象(称之为dynbs).每个都有n=1000000位.对于上面给定的方法,n按顺序调用每个位上的方法并重复此次R=10000.
使用该std::chrono库,以下是每纳秒的时间:
set
bitset: 267 nsecs
dyn bitset: 18603174546 nsecs
flip
bitset: 73 nsecs
dyn bitset: 18842352867 nsecs
count
bitset: 77 nsecs
dyn bitset: 51 nsecs
Run Code Online (Sandbox Code Playgroud)
boost::dynamic_bitset对于set和,似乎要慢得多flip.
为了使它更有趣,如果reset在运行这些测试之前在两个对象上调用该方法,那么时序是可比较的.他们来了:
set
bitset: 19397779399 nsecs
dyn bitset: 18472863864 nsecs
flip
bitset: 18599248629 nsecs
dyn bitset: 18376267939 nsecs …Run Code Online (Sandbox Code Playgroud) 如何使用boost :: dynamic_bitset成员序列化一个类?
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/dynamic_bitset.hpp>
#include <boost/serialization/bitset.hpp>
#include <sstream>
class A
{
friend class boost::serialization::access;
boost::dynamic_bitset<> x;
template<class Archive>
void serialize(Archive & ar, const unsigned int){
ar & x;
}
};
int main()
{
A a;
std::stringstream ss;
boost::archive::text_oarchive oa(ss);
oa << a;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
编译给出错误(提升1.57)
In file included from /usr/include/boost/serialization/extended_type_info_typeid.hpp:37:0,
from /usr/include/boost/archive/detail/oserializer.hpp:38,
from /usr/include/boost/archive/detail/interface_oarchive.hpp:23,
from /usr/include/boost/archive/detail/common_oarchive.hpp:22,
from /usr/include/boost/archive/basic_text_oarchive.hpp:32,
from /usr/include/boost/archive/text_oarchive.hpp:31,
from dynamic_bitset_setial.cpp:1:
/usr/include/boost/serialization/access.hpp: In static member function ‘static void boost::serialization::access::serialize(Archive&, T&, unsigned int) [with …Run Code Online (Sandbox Code Playgroud) 我在这里讲述一个长篇大论的背景故事,因为除了直接回答之外,我想知道导致这种情况的推理是否正确.
我有一个带dynamic_bitset<>参数的函数(来自Boost.dynamic_bitset).说它看起来像这样.
void foo(boost::dynamic_bitset<> db) {
// do stuff
}
Run Code Online (Sandbox Code Playgroud)
碰巧它只是用构造函数构建的临时函数foo(boost::dynamic_bitset<>{5}.set())调用,如同(用5位bitset调用所有位设置).
我的位集只有少量位(少于32位).所以起初,我想"我只是按值传递它;副本比指针小." 但后来我想"它是动态的,所以它必须在堆上分配空间.我想避免不必要的分配和释放."
所以,我可以做到
void foo(const boost::dynamic_bitset<>& db);
Run Code Online (Sandbox Code Playgroud)
但是引用是一个指针,而dynamic_bitset(可能)有一个指向其数据的指针,因此使用dbwithin foo会经历两个间接级别,这看起来很愚蠢.显然,最好的方法是将指针复制到数据中foo,而无需重新分配和复制堆上的数据.
"啊哈!" 我说."当然这就是语义学的用途." 所以,我将签名更改为
void foo(boost::dynamic_bitset<>&& db);
Run Code Online (Sandbox Code Playgroud)
但是,调用foo(boost::dynamic_bitset<>{5}.set())会产生编译错误cannot bind 'boost::dynamic_bitset<>' lvalue to 'boost::dynamic_bitset<>&&'.我必须打电话
foo(std::move(boost::dynamic_bitset<>{5}.set()))
然后一切正常.
为什么我需要调用std :: move? 这似乎显然是一个xvalue(临时即将到期),不是吗?
我有一个 7 字节/56 位位集,在构造时将第一位设置为 1:
boost::dynamic_bitset<> b(56, 1);
Run Code Online (Sandbox Code Playgroud)
构造完成后,我想将一个整数值(比如 2019)放入第 4 位到第 15 位中。我很好奇 boost 中是否有一种简单的方法可以在不进行按位运算的情况下实现此目的?基本上,我想将一系列位设置为一个整数值,我知道该整数值足够小以适合这些位。感谢您的任何建议。
我试图使用set的dynamic_bitset对象,但我在运行时得到一个断言失败:
a.out: boost/dynamic_bitset/dynamic_bitset.hpp:1291:
bool boost::operator<(const boost::dynamic_bitset<Block, Allocator>&,
const boost::dynamic_bitset<Block, Allocator>&)
[with Block = long unsigned int,
Allocator = std::allocator<long unsigned int>]:
Assertion `a.size() == b.size()' failed.
Run Code Online (Sandbox Code Playgroud)
这是代码:
#include <iostream>
#include <set>
#include <boost/dynamic_bitset.hpp>
int main() {
typedef boost::dynamic_bitset<> bitset;
std::set<bitset> myset;
bitset x(2, 0);
bitset y(3, 1);
myset.insert(x);
myset.insert(y);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我想知道为什么插入的dynamic_bitset对象需要相同的大小。为了operator<起作用,是否不能假设较短位集中的最高有效位隐式地用零填充?
有什么办法可以使这套dynamic_bitsets起作用?
我也尝试过a,unordered_set因为它不需要the,operator<但是由于dynamic_bitset没有a hash_value而不能编译,而且我不确定如何在不使用其to_ulong成员函数的情况下编写该函数,该函数仅适用于短位集。