【发布时间】:2015-08-11 16:25:39
【问题描述】:
这个问题一开始就有点代码,只是因为我觉得更容易看出我在追求什么:
/*static*/
void
Url::Split
(std::list<std::string> & url
, const std::string& stringUrl
)
{
std::string collector;
collector.reserve(stringUrl.length());
for (auto c : stringUrl)
{
if (PathSeparator == c)
{
url.push_back(collector);
collector.clear(); // Sabotages my optimization with reserve() above!
}
else
{
collector.push_back(c);
}
}
url.push_back(collector);
}
在上面的代码中,collector.reserve(stringUrl.length()); 行应该减少在下面的循环期间执行的堆操作量。毕竟,每个子字符串都不能比整个 url 长,所以像我一样保留足够的容量看起来是个好主意。
但是,一旦子字符串完成并将其添加到 url 部件列表中,我需要以一种或另一种方式将字符串重置为长度 0。简短的“窥视定义”检查向我表明,至少在我的平台上,保留的缓冲区将被释放,因此我的 reserve() 调用的目的就受到了损害。
它在内部调用一些_Eos(0)以防万一。
我也可以使用 collector.resize(0) 完成相同的操作,但窥视定义显示它也在内部调用 _Eos(newsize),因此行为与调用 clear() 的情况相同。
现在的问题是,是否有一种可移植 方法来建立预期的优化,以及哪个std::string 函数可以帮助我。
当然我可以写collector[0] = '\0';,但这对我来说很不合适。
旁注:虽然我发现了类似的问题,但我认为这不是其中任何一个的重复。
谢谢,提前。
【问题讨论】:
-
好问题:
clear永远不会替换缓冲区是一个常见的假设,但我在 C++11 中看不到任何这样的保证。可能存在但不明显。 -
“上面的 reserve() 破坏了我的优化!” 是吗?
-
@LightnessRacesinOrbit 现在不行,不在我当前的平台上。但我想我记得一些平台的实现看起来完全不同。不确定它是否是纯粹的实现之一,或者它是否是 SGI……嗯……那是几年前的事了。
-
@BitTickler:C++ 现在已经标准化了。