我有一个结构,我将函数作为常量指针传递给我,我的问题如下:函数updatedFields的这两个实现之间存在差异:
typedef struct
{
int spec[100];
int spec1[200];
int spec2[200];
int spec3[500];
int spec4[100];
int spec5[700];
float value[100];
char desc[1000]:
}t_product;
void updateFields_1(t_product const* context)
{
int i,buffer[1500];
int * pt_int;
pt_int = (int*)context->spec1;
for(i = 0; i < 200; i++)
{
buffer[i] = pt_int[i];
}
pt_int = (int*)context->spec3;
for(i = 0; i < 500; i++)
{
buffer[i] = pt_int[i];
}
...
}
void updateFields_2(t_product const* context)
{
int i,buffer[1500];
for(i = 0; i < 200; i++)
{
buffer[i] = context->spec1[i];
}
for(i = 0; i < 500; i++)
{
buffer[i] = context->spec3[i];
}
...
}
int main(void)
{
t_product prod;
/* Initialisation of the structure */
...
updateField(&prod);
}
我的意思是,使用指向结构成员的指针(指向数组的指针)而不是直接访问结构成员有任何好处。
这可能是一个愚蠢的问题,但我不知道结构成员的访问是否成本&#34;更多的操作。
答案 0 :(得分:2)
在您的情况下,它不会花费更多。即使没有优化。实际上,如果您不启用优化,那么您的pt_int
示例可能会稍差一些。
这是因为context->spec3[i]
没有取消引用比pt_int[i]
更多的指针。 pt_int[i]
只是一个指针加上一个偏移量,因此访问权限可以写成@(ptr_int + 4*i)
。在context->spec3[i]
中,看起来有一个指针被解除引用,但情况并非如此。 spec3
不是context
中的值,它只是与上下文的偏移量。因此,您访问的地址为@(context + 2000 + 4*i)
。只有一个指针访问。
现在您可以想知道@(context + 2000 + 4*i)
的费用是否高于@(ptr_int + 4*i)
。它没有,因为大多数架构,包括x86,AMD64和ARM(即100%的个人设备),都有使用常量偏移进行访问的指令。此外,当您启用简单的优化时,差异可能很快消失,因为context + 2000
可以转换为单个context_2000
(但编译器实际上不会这样做,因为它只会恶化性能)。 / p>
答案 1 :(得分:1)
它确实花费更多(它必须在每次迭代时取消引用原始指针),但成本可能很小,并且一个不错的编译器将为您进行优化。