我想知道实用函数中内存分配过程的成本有多大。例如下面的实现有很大的区别吗?
string method_A (string inp) {
auto num_fillers = inp.length() - 4;
string filler(num_fillers, '-');
string res = filler + inp.substr(num_fillers);
return res;
}
string method_B (string inp) {
const int expect_len =4;
auto num_fillers = inp.length() - expect_len;
string res;
res.reserve(num_fillers + expect_len);
res.assign(num_fillers, '-');
res+= inp.substr(num_fillers);
return res;
}
Run Code Online (Sandbox Code Playgroud)
使用 method_B 代替 method_A 有什么好处吗?各自的优点和缺点是什么?
分配一次内存并用“+=”操作填充字符串是否比method_A中的做法有更好的性能?
分配确实会产生开销,并且在实际情况下最好避免不必要的开销。但除非必要,否则不会以牺牲可维护性/复杂性为代价。所以你应该始终权衡这一点。
对于标准库来说,没有realloc等效的。附加到动态容器通常涉及分配、复制和删除(忽略小字符串优化和预先保留的容量)。如果您在程序中经常这样做,您可能需要考虑内存碎片的可能性。
就您而言,您正在进行大量分配。
方法一:
string inp参数按值传递filler构造函数分配另一个字符串inp.substr(num_fillers)分配另一个字符串operator+分配另一个字符串方法B(目前充满错误):
string inp参数按值传递res.reserve(num_fillers + expect_len)分配另一个字符串inp.substr(num_fillers)分配另一个字符串所以,情况并没有好多少。您避免了一项分配,但仍然进行了三项分配。分配较少的方法(基于您在 中的尝试method_B)将是:
std::string method_C(const std::string& inp)
{
const std::size_t expect_len = 4;
const std::size_t num_fillers = inp.size() - std::min(inp.size(), expect_len);
std::string res;
res.reserve(num_fillers + expect_len);
res.assign(num_fillers, '-');
res.append(inp.begin() + num_fillers, inp.end());
return res;
}
Run Code Online (Sandbox Code Playgroud)
上面只执行了一次分配。
append如果您确实喜欢使用,则substr可以使用以下替代方法std::string_view:
res += std::string_view(inp).substr(num_fillers);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
141 次 |
| 最近记录: |