Log*_*ldo 81
compressed_pair
使用一些模板技巧来节省空间.在C++中,对象(小o)不能具有与不同对象相同的地址.
所以,即使你有
struct A { };
Run Code Online (Sandbox Code Playgroud)
A
的大小不会是0,因为那样:
A a1;
A a2;
&a1 == &a2;
Run Code Online (Sandbox Code Playgroud)
会坚持,这是不允许的.
但是许多编译器会做所谓的"空基类优化":
struct A { };
struct B { int x; };
struct C : public A { int x; };
Run Code Online (Sandbox Code Playgroud)
在这里,它是罚款B
,并C
具有相同的尺寸,即使sizeof(A)
不能为零.
因此boost::compressed_pair
,利用此优化,并且如果可能的话,如果它是空的,则将继承该对中的一个或另一个类型.
所以std::pair
可能看起来像(我已经省略了很多,ctors等):
template<typename FirstType, typename SecondType>
struct pair {
FirstType first;
SecondType second;
};
Run Code Online (Sandbox Code Playgroud)
这意味着,如果任一FirstType
或者SecondType
是A
,你pair<A, int>
必须比更大sizeof(int)
.
但是如果你使用compressed_pair
,它生成的代码将类似于:
struct compressed_pair<A,int> : private A {
int second_;
A first() { return *this; }
int second() { return second_; }
};
Run Code Online (Sandbox Code Playgroud)
并且compressed_pair<A,int>
只会与sizeof(int)一样大.
Dav*_*rre 11
有时你需要从一个函数中返回2个值,并且为此创建一个类通常是过度的.
std:pair在这些情况下派上用场.
我认为boost:compressed_pair能够优化大小为0的成员.这对于库中的重模板机制来说非常有用.
如果你直接控制类型,那就无关紧要了.
Joh*_*itb 11
听到compressed_pair关心几个字节听起来很奇怪.但是当考虑可以使用compressed_pair的位置时,它实际上很重要.例如,让我们考虑一下这段代码:
boost::function<void(int)> f(boost::bind(&f, _1));
Run Code Online (Sandbox Code Playgroud)
在上述情况下使用compressed_pair会突然产生很大的影响.如果boost :: bind将函数指针和占位符存储_1
为成员本身或std::pair
本身存在,会发生什么?好吧,它可能会膨胀sizeof(&f) + sizeof(_1)
.假设函数指针有8个字节(对于成员函数来说并不罕见)并且占位符有一个字节(请参阅Logan的答案原因),那么我们可能需要9个字节用于绑定对象.由于对齐,在通常的32位系统上,这可能会膨胀到12个字节.
boost::function
鼓励其实现应用小对象优化.这意味着对于小型仿函数,直接嵌入boost::function
对象中的小缓冲区用于存储仿函数.对于较大的仿函数,必须使用operator new来获取内存.在升级版本1.34之后,决定采用这种优化,因为它被认为可以获得一些非常好的性能优势.
现在,这种小缓冲区的合理(但可能仍然非常小)限制将是8个字节.也就是说,我们非常简单的绑定对象不适合小缓冲区,并且需要存储new运算符.如果上面的绑定对象使用a compressed_pair
,它实际上可以将其大小减小到8个字节(或者经常是非成员函数指针的4个字节),因为占位符只不过是一个空对象.
因此,看起来只是浪费了很多想法,实际上只会对性能产生重大影响.
归档时间: |
|
查看次数: |
40123 次 |
最近记录: |