Reputation: 71
int n = strlen(s)
for (int i = 0; i < n; i++)
{
printf("%c", s[i]);
}
for (int i = 0; i <strlen(s); i++)
{
printf("%c", s[i]);
}
What I'm trying to ask is what is happening in memory(under the hood). Let's say the string length is 4, is 4 assigned to n, and would that make it easier for the compiler to compile? In the second code, would the compiler have to check what the string length of s is over and over? Is the point of the first code to make the compiler remember the string length is so it doesn't need to check for it every time. I'm sorry if my question isn't clear enough, telling me how to improve would be greatly appreciated.
Upvotes: 1
Views: 75
Reputation: 67476
The main difference is that the first loop will call strlen
on every iteration.
int foo(const char *s)
{
for (int i = 0; i <strlen(s); i++)
{
printf("%c", s[i]);
}
return 0;
}
int bar(const char *s)
{
int n = strlen(s);
for (int i = 0; i < n; i++)
{
printf("%c", s[i]);
}
return n;
}
and the resulting code:
foo:
push rbp
mov rbp, rdi
push rbx
xor ebx, ebx
sub rsp, 8
jmp .L2
.L3:
movsx edi, BYTE PTR [rbp+0+rbx]
add rbx, 1
call putchar
.L2:
mov rdi, rbp
call strlen
cmp rax, rbx
ja .L3
add rsp, 8
xor eax, eax
pop rbx
pop rbp
ret
bar:
push r12
push rbp
push rbx
mov rbx, rdi
call strlen
mov r12, rax
test eax, eax
jle .L6
lea eax, [rax-1]
lea rbp, [rbx+1+rax]
.L8:
movsx edi, BYTE PTR [rbx]
add rbx, 1
call putchar
cmp rbx, rbp
jne .L8
.L6:
mov eax, r12d
pop rbx
pop rbp
pop r12
ret
(gcc -O3) https://godbolt.org/z/1oh991
Upvotes: 1
Reputation: 26066
In the second code, would the compiler have to check what the string length of s is over and over
That's exactly right. The condition of a for
loop is evaluated every iteration. Therefore, you should cache the length (or any other result that does not change in each iteration, for that matter).
In this case, as people pointed out, you can do even better avoiding to compute the length since you are iterating the string anyway.
Upvotes: 1