Рассмотрим следующий код:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
class chartolower {
private:
char s[50000];
public:
void populates(int index, int val) { s[index] = val; }
size_t strlen(const char *s) const {
long length = 0;
while (*s != '\0') {
s++;
length++;
}
return length;
}
/*Convert string to lower case: slow*/
void lower1() {
long i;
for (i = 0; i < strlen(s); i++)
if (s[i] >= 'A' && s[i] <= 'Z')
s[i] -= ('A' - 'a'); //Case(1) strlen(s) not optimized away
//i = i; //Case(2) strlen(s) optimized away
//if(s[i] != '\0') s[i] = s[i];//Case(3) strlen(s) not optimized away
//s[i] = s[i]; //Case(4) strlen(s) not optimized away
}
};
int main() {
chartolower s;
for (int i = 0; i < 49999; i++)
s.populates(i, 65);//ASCII for A
s.populates(49999, '\0');
clock_t start_t, end_t, total_t;
start_t = clock();
s.lower1();
end_t = clock();
total_t = (end_t - start_t);
printf("Total time taken by CPU Lower 1: %d\n", total_t);
getchar();
}
На моем компьютере (Visual Studio 2017, Release Mode Build) выводятся 4 случая:
Case(1) Total time taken by CPU Lower 1: 3477
Case(2) Total time taken by CPU Lower 1: 0
Case(3) Total time taken by CPU Lower 1: 3445
Case(4) Total time taken by CPU Lower 1: 3455
Случай (1), Я могу понять, почему strlen(s)
строки for (i = 0; i < strlen(s); i++)
не оптимизировано, поскольку s[i]
можно изменить.Случай (2) оптимизирован, поскольку s[i]
для всех i
остается без изменений.В случае (3) мне не понятно, почему компилятор не может оптимизировать strlen(s)
.Я ожидал, что компилятор выяснит, что strlen(s)
должен вычислять, пока не встретит \0
, и это именно то условие, которое проверяется в случае (3).Случай (4) также не оптимизируется, и я бы подумал, что его следует оптимизировать, поскольку он аналогичен случаю (2).
Что вызывает оптимизацию в случае (2), но не в других случаях