Что потрачено впустую в примере из Cpp Core Guidelines?
P.9: не тратьте время и пространство
[…]void lower(zstring s) { for (int i = 0; i < strlen(s); ++i) s[i] = tolower(s[i]); }
Да, это пример из производственного кода. Мы оставляем читателю понять, что было потрачено впустую.
от 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
является (или неявно преобразуемым) char
массив, так как это то, что strlen
надеется. Таким образом, мы можем просто использовать это свойство для нашего собственного цикла.
void lower(zstring s) {
for (char *p = s; *p; ++p)
*p = std::tolower((unsigned char)*p);
}