Goz*_*Goz 38 c++ optimization stl vector
我正在对一段代码进行快速性能测试
void ConvertToFloat( const std::vector< short >& audioBlock,
std::vector< float >& out )
{
const float rcpShortMax = 1.0f / (float)SHRT_MAX;
out.resize( audioBlock.size() );
for( size_t i = 0; i < audioBlock.size(); i++ )
{
out[i] = (float)audioBlock[i] * rcpShortMax;
}
}
Run Code Online (Sandbox Code Playgroud)
我很高兴原来非常天真的实现速度超过1毫秒来处理65536个音频样本.
然而,只是为了好玩,我尝试了以下
void ConvertToFloat( const std::vector< short >& audioBlock,
std::vector< float >& out )
{
const float rcpShortMax = 1.0f / (float)SHRT_MAX;
out.reserve( audioBlock.size() );
for( size_t i = 0; i < audioBlock.size(); i++ )
{
out.push_back( (float)audioBlock[i] * rcpShortMax );
}
}
Run Code Online (Sandbox Code Playgroud)
现在我完全希望它能提供与原始代码完全相同的性能.然而,突然循环现在正在采用900usec(即它比其他实现快100usec).
谁能解释为什么这会带来更好的表现?是否resize()
初始化新分配的向量,其中储备只是分配,但不建?这是我唯一能想到的.
PS这是在单核2Ghz AMD炫龙64 ML-37上测试的.
sep*_*p2k 62
resize是否初始化新分配的向量,其中reserve只分配但不构造?
是.
调整大小()
修改容器,使其恰好有 n 个元素,如有必要,在末尾插入元素或从末尾删除元素。如果插入任何元素,则它们是 t 的副本。如果n > a.size()
,该表达式等价于a.insert(a.end(), n - size(), t)
。如果n < a.size()
,则等价于a.erase(a.begin() + n, a.end())
。
预订()
如果 n 小于或等于capacity()
,则此调用无效。否则,它是一个分配额外内存的请求。如果请求成功,则capacity()
大于等于n;否则,capacity()
不变。在任何一种情况下,size()
都是不变的。
如果capacity() - size()
在向量中插入了多个元素,内存将自动重新分配。重新分配不会改变size()
,也不会改变向量的任何元素的值。然而,它确实增加了capacity()
Reserve 导致手动重新分配。使用的主要原因reserve()
是效率:如果您知道向量最终必须增长到的容量,那么一次性分配所有内存通常比依赖自动重新分配方案更有效。