Использует ли strlen() условие цикла медленнее, чем просто проверка нулевого символа?
Я читал, что использование strlen
дороже, чем такое тестирование:
У нас есть строка x
длиной 100 символов.
Я думаю, что
for (int i = 0; i < strlen(x); i++)
дороже, чем этот код:
for (int i = 0; x[i] != '\0'; i++)
Это правда? Может быть, второй код не будет работать в какой-то ситуации, так лучше ли использовать первый?
Будет ли лучше с нижним?
for (char *tempptr = x; *tempptr != '\0'; tempptr++)
Ответы
Ответ 1
for (int i=0;i<strlen(x);i++)
Этот код вызывает strlen(x)
каждую итерацию. Поэтому, если x
- длина 100, strlen(x)
будет называться 100 раз. Это очень дорого. Кроме того, strlen(x)
также выполняет итерацию по x
каждый раз так же, как это делает цикл for. Это делает сложностью O (n ^ 2).
for (int i=0;x[i]!='\0';i++)
Этот код не вызывает никаких функций, поэтому будет намного быстрее, чем предыдущий пример. Поскольку он повторяется через цикл только один раз, это сложность O (n).
Ответ 2
Первый код проверяет длину x на каждой итерации я и принимает O (n), чтобы найти последнее 0, поэтому он принимает O (n ^ 2), второй случай O (n)
Ответ 3
Да, ваша вторая может не работать в 100% случаев, но это было бы немного. Это связано с тем, что при использовании strlen() вы должны каждый раз вызывать метод. Лучший способ был бы таким образом
int strLength = strlen(x);
for (int i = 0; i < strLength; i++)
Надеюсь, что это поможет.
Ответ 4
Я могу предположить, что в первом варианте вы найдете strlen каждую итерацию, а во втором варианте вы этого не делаете.
Попробуйте это, чтобы проверить:
int a = strlen(x);
for (int i = 0; i < a; i++) {...}
Ответ 5
Если нет оптимизации компиляции. Да потому, что strlen будет перебирать каждый байт строки каждый раз, а вторая реализация будет делать это только один раз.
Ответ 6
Я думаю, что компилятор мог бы оптимизировать (отметьте комментарий Грегори Пакоса) свой первый цикл for, чтобы вы были такими:
int len = strlen(x);
for (int i = 0; i < len; i++)
Это еще O(n)
.
В любом случае, я думаю, ваш второй цикл for
будет быстрее.
Ответ 7
Конечно, первая займет больше секунды. Они вообще не делают то же самое - первый из них вычисляет длину строки каждый раз; второй (фактически) делает это только один раз.
Первая версия эквивалентна следующей:
for (int i=0; x[i] != 0; i++)
for (int j=0; j<i; j++)
;
Возможно, вы хотели сказать "эффективнее ли вызывать библиотеку strlen(), чем реализовать мою собственную?" Ответ на это, конечно, "это зависит". У вашего компилятора могут быть встроенные версии strlen(), которые оптимизированы за пределами того, что вы ожидаете от источника, вы можете быть на платформе, по которой вызовы функций дороги (редко в настоящее время) и т.д.
Единственный ответ, что и общий, и правильный - это "профиль и узнать".
Ответ 8
Стоит отметить, что вы можете открывать проблемы с переполнением буфера, если вы также не проверяете индекс на размер буфера, содержащего строку. В зависимости от того, что вы делаете с этим кодом, это может быть или не быть практической проблемой, но редко бывает больно иметь дополнительные проверки, и это хорошая привычка входить.
Я бы предложил: для (i = 0; я < buf_size & x [i]!= '\ 0'; я ++)
Где:
-
buf_size
- заданный размер буфера. Если x
- массив, это будет sizeof(x)
; если x
- указатель, вы должны иметь размер буфера.
- Я удалил объявление
i
из цикла, потому что он действителен только c99. Если вы компилируете только в c99, не стесняйтесь возвращать его.