1

因此,在对性能敏感的应用程序中,有很多情况需要它,而我终于找到了压倒骆驼的稻草。它需要在 C++98 中编译,因为我们至少有一个平台只保证符合 C++98。

希望对我想要的内容进行编辑以更清楚地说明。

例子:

// This will allocate storage for 1024, and then loop 1024 times touching all of it just to place a 0 in it 
std::vector< char > buffer( 1024 );
// Now read will write into that buffer, overwriting the 0s ( we payed for the fill unnecessarily ) 
buffer.resize( read( someSource, &buffer[0], buffer.size() ) );

这是通用的 C 接口,几乎与所有 C 库一起用于将数据写入缓冲区。通常在处理包含原语的缓冲区时也会出现同样的问题。新的调整大小看起来像这样:

// Disabled for anything which doesn't pass boost::is_POD< T >, they get the standard version
void resize( size_t a_NewSize )
{
     reserve( a_NewSize );
     _end = _begin + a_NewSize;
}

construct_back 将是一个转发构造函数,对于 1 个 const 参数,它看起来像这样(未经测试):

template< typename T1 >
void construct_back( const T1& a_Arg1 )
{
    if( capacity() <= size() ) // No room
         reserve( size() + 1 );
    // Construct in place using Ts constructor that accepts const T1&
    new (&(*end()) T( T1 );
    ++_end; // Account for new element
}

construct_back 必须具有所有可能数量的参数^2 重载,这是 C++98 中完美转发的常见蛮力方法。

4

3 回答 3

3

要在向量中预分配内存,请使用vector::reserve. 这不仅适用于原始类型,也适用于所有类型。

要在适当位置构造元素,您需要将 C++11 与Boost.Containersvector::emplace_back提供的容器或其中一个容器一起使用。

如果您需要惰性构造(因为您的构造函数很昂贵)std::vector<boost::optional>是一个很好的解决方案。

于 2012-03-07T09:00:06.740 回答
1

您的编译器可能足够聪明,可以避免初始化。(如果它内联所有内容并且您仅在本地使用此向量,则推断初始化已过时并不太复杂。)

否则:

如果你非常关心性能,而且如果你有一个固定大小的缓冲区,为什么不在堆栈上使用一个数组呢?IE:

char buffer[1024];
size_t blen = read( someSource, buffer, sizeof(buffer) );

您还避免了在这种情况下引入的堆的间接性std::vector

您还可以围绕它构建自己的模板容器,即:

template<typename T = char, size_t MaxSize = 1024>
struct Buffer {
    static const size_t maxsize = MaxSize;
    typedef T type;
    type data[maxsize];
    size_t len;
    Buffer() : len(0) {}
};

并根据需要在其中插入任何其他功能(使其类似于 STL 容器)。

于 2012-03-09T01:07:40.030 回答
0
v1.reserve( 200 );

使用保留可以减少调整大小的次数 在MSDN上阅读有关保留的更多信息

于 2012-03-07T09:03:46.597 回答