再次[]
和*
:
void func(const instance* I, const float* in, float* out)
{
for(int i=0;i<N; i++)
{
// some calculation goes here
out[i] = ... in[i] * I.something[i] ... ;
}
}
我经常发现子函数代码的编写方式不是用[]
引用数组,而是引入了额外的指针,例如:
void func(const instance* I, const float* in, float* out)
{
const float* inp = in;
float* outp = out;
float* s = I->something;
for(int i=0;i<N; i++)
{
// some calculation goes here
outp++ = ... inp++ * s++ ... ;
}
}
这样做的主要原因是:可读性,性能或其他?它对性能有影响吗?
答案 0 :(得分:2)
这样做的主要原因是什么: 可读性,性能还是其他? 它对性能有影响吗?
示例:
char *mystrcpy(char *dest, const char *src)
{
char *workdest = dest; // temp variable to be used instead of dest.
while((*workdest++ = *src++));
return dest;
}
如果使用优化的编译器(并启用优化),通常对性能没有任何影响
引入新的(理论上不需要的变量)可能有助于将复杂的逻辑拆分为更易于维护的较小部分。通常,它也不会对性能产生任何影响,因为编译器通常会很好地对其进行优化。
索引和指针算术具有相同的性能,并且在大多数情况下,生成的代码是相同的。
示例:
int *reverse(int *arr, size_t size)
{
int *end, *saved = arr;
if(arr && size > 1)
{
end = arr + size - 1;
while(end > arr)
{
int tmp = *arr;
*arr++ = *end;
*end-- = tmp;
}
}
return saved;
}
int *reverse1(int *arr, size_t num)
{
if(arr && num > 1)
{
for(size_t i = 0; i < num/2; i++)
{
int temp;
temp=arr[i];
arr[i] = arr[num-(i+1)];
arr[num-(i+1)]=temp;
}
}
return arr;
}
及其结果代码:
reverse:
mov r8, rdi
test rdi, rdi
je .L2
cmp rsi, 1
jbe .L2
lea rax, [rdi-4+rsi*4]
cmp rdi, rax
jnb .L2
mov rdx, rdi
.L3:
mov ecx, DWORD PTR [rdx]
mov esi, DWORD PTR [rax]
add rdx, 4
sub rax, 4
mov DWORD PTR [rdx-4], esi
mov DWORD PTR [rax+4], ecx
cmp rdx, rax
jb .L3
.L2:
mov rax, r8
ret
reverse1:
mov r8, rdi
test rdi, rdi
je .L18
cmp rsi, 1
jbe .L18
lea rdx, [rdi-4+rsi*4]
shr rsi
mov rax, rdi
lea rdi, [rdi+rsi*4]
.L15:
mov esi, DWORD PTR [rdx]
mov ecx, DWORD PTR [rax]
add rax, 4
sub rdx, 4
mov DWORD PTR [rax-4], esi
mov DWORD PTR [rdx+4], ecx
cmp rax, rdi
jne .L15
.L18:
mov rax, r8
ret