Что потеряно в этом примере из основных принципов Cpp?

Что потрачено впустую в примере из Руководства Cpp Core?

Стр .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

Ответ 1

strlen вычисляется на каждой итерации цикла.

Ответ 2

strlen вызывается каждый раз, когда проверяется условие цикла, и принимает O (n) время на вызов, поэтому общее время цикла равно O (n ^ 2).

Ответ 3

Много времени тратится впустую, и ошибка сегментации может возникать как автор кода, увеличивающий s, а не i в цикле:

for (int i = 0; i < strlen(s); ++s)
                 //right here ^^^^

Ответ 4

Как уже указывали другие участники, strlen(s) вызывается несколько раз, потому что он находится в условии, подразумевая, что он должен быть кэширован и повторно использован.

Но strlen(s) вообще не нужно называть! s является (или неявно конвертируется) в nul-terminated char массив, так как это ожидает strlen. Поэтому мы можем просто использовать это свойство для нашего собственного цикла.

void lower(zstring s) {
    for (char *p = s; *p; ++p)
        *p = std::tolower((unsigned char)*p);
}

Ответ 5

Если в классе zstring не существует какой-либо очень неинтуитивной семантики, функция в ее текущей форме является пустой тратой пространства времени и, поскольку ее "результат" не может использоваться после функции - оно передается как значение и не возвращается.

Поэтому, чтобы не тратить время на бесполезное вычисление строчных букв, которые нельзя использовать, а также на пространство при копировании переданного параметра, я бы передал ссылку!