Cpp Core Guidelines 在这个例子中浪费了什么?
What is wasted in this example from the Cpp Core Guidelines?
Cpp 核心指南中的示例浪费了什么?
P.9: Don't waste time or space
[...]
void lower(zstring s)
{
for (int i = 0; i < strlen(s); ++i) s[i] = tolower(s[i]);
}
Yes, this is an example from production code. We leave it to the reader to figure out what's wasted.
来自 https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#Rp-waste
每次循环迭代都会计算 strlen。
strlen
每次检查循环条件时调用,每次调用花费 O(n) 时间,因此循环的总时间为 O(n^2).
由于代码的作者在循环中递增s
,而不是i
,因此浪费了很多时间并且可能会出现段错误:
for (int i = 0; i < strlen(s); ++s)
//right here ^^^^
正如其他回答者已经指出的那样,strlen(s)
被多次调用,因为它处于条件中,这意味着它应该被缓存并重用。
但是 strlen(s)
实际上根本不需要调用! s
是(或可隐式转换为)一个以 nul 结尾的 char
数组,因为那是 strlen
所期望的。所以我们可以将这个 属性 用于我们自己的循环。
void lower(zstring s) {
for (char *p = s; *p; ++p)
*p = std::tolower((unsigned char)*p);
}
除非它们在 zstring
class 中有任何非常不直观的语义,否则当前形式的函数完全是在浪费时间 和 space,因为它的 "result" 不能在函数之后使用 - 它作为值传入,不会返回。
所以为了避免浪费时间去无用地计算不能使用的小写字母,以及space在复制传递的参数时,我会按引用传递!
Cpp 核心指南中的示例浪费了什么?
P.9: Don't waste time or space
[...]
void lower(zstring s) { for (int i = 0; i < strlen(s); ++i) s[i] = tolower(s[i]); }
Yes, this is an example from production code. We leave it to the reader to figure out what's wasted.
来自 https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#Rp-waste
每次循环迭代都会计算 strlen。
strlen
每次检查循环条件时调用,每次调用花费 O(n) 时间,因此循环的总时间为 O(n^2).
由于代码的作者在循环中递增s
,而不是i
,因此浪费了很多时间并且可能会出现段错误:
for (int i = 0; i < strlen(s); ++s)
//right here ^^^^
正如其他回答者已经指出的那样,strlen(s)
被多次调用,因为它处于条件中,这意味着它应该被缓存并重用。
但是 strlen(s)
实际上根本不需要调用! s
是(或可隐式转换为)一个以 nul 结尾的 char
数组,因为那是 strlen
所期望的。所以我们可以将这个 属性 用于我们自己的循环。
void lower(zstring s) {
for (char *p = s; *p; ++p)
*p = std::tolower((unsigned char)*p);
}
除非它们在 zstring
class 中有任何非常不直观的语义,否则当前形式的函数完全是在浪费时间 和 space,因为它的 "result" 不能在函数之后使用 - 它作为值传入,不会返回。
所以为了避免浪费时间去无用地计算不能使用的小写字母,以及space在复制传递的参数时,我会按引用传递!