gpt4 book ai didi

c++ - 关于 std::string Action 的实现

转载 作者:IT老高 更新时间:2023-10-28 23:21:51 32 4
gpt4 key购买 nike

我正在调查 move std::string 的性能.很长一段时间以来,我一直认为字符串 move 几乎是免费的,认为编译器会内联所有内容,并且只涉及一些廉价的赋值。

事实上,我 move 的心智模式确实是

string& operator=(string&& rhs) noexcept
{
swap(*this, rhs);
return *this;
}

friend void swap(string& x, string& y) noexcept
{
// for disposition only
unsigned char buf[sizeof(string)];
memcpy(buf, &x, sizeof(string));
memcpy(&x, &y, sizeof(string));
memcpy(&y, buf, sizeof(string));
}

据我所知,如果 memcpy改为分配单个字段。

发现gcc的 move 实现涉及到creating a new string and might possibly throw due to the allocations despite being noexcept ,这让我大吃一惊。 .

这是否符合要求?同样重要的是,我不应该认为搬家几乎是免费的吗?


令人困惑的是, std::vector<char> compiles down符合我的预期。

clang's implementation有很大不同,虽然有一个可疑的std::string::reserve

最佳答案

我只分析了 GCC 的版本。这是发生了什么:代码处理不同类型的分配器。如果分配器具有 _S_propagate_on_move_assign_S_always_equal 的特征,那么正如您所料, move 几乎是免费的。这是 move operator= 中的 if:

if (!__str._M_is_local()
&& (_Alloc_traits::_S_propagate_on_move_assign()
|| _Alloc_traits::_S_always_equal()))
// cheap move
else assign(__str);

如果条件为真(_M_is_local() 表示小字符串,描述 here ),则此举很便宜。

如果它是假的,那么它调用正常 assign(不是 move 的)。在以下任一情况下都会出现这种情况:

  • 字符串很小,所以 assign 会做一个简单的 memcpy(便宜)
  • 或者分配器没有 always-equalpropagate-on-move-assign 的特性,所以分配器将分配 (不便宜)

这是什么意思?

这意味着,如果您使用默认分配器(或任何具有前面提到的特征的分配器),那么 move 仍然几乎是免费的

另一方面,生成的代码不必要地庞大,我认为可以改进。它应该有一个单独的代码来处理通常的分配器,或者有一个更好的 assign 代码(问题是 assign 不检查 _M_is_local(),但它会进行容量检查,因此编译器无法决定是否需要分配,因此它会将分配代码路径不必要地放入可执行文件中 - 您可以查看源代码中的确切详细信息。

关于c++ - 关于 std::string Action 的实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50586818/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com