说我有类似下面的结构...
typedef struct {
int WheelCount;
double MaxSpeed;
} Vehicle;
......我有这种类型的全局变量(我很清楚全局的陷阱,这是一个嵌入式系统,我没有设计,以及他们是不幸的,但必要的罪恶。 )它更快,直接或通过指针访问结构的成员? 即
double LocalSpeed = MyGlobal.MaxSpeed;
要么
double LocalSpeed = pMyGlobal->MaxSpeed;
我的一个任务是简化和修复最近继承嵌入式系统。
在一般情况下,我会说去的第一个选项:
double LocalSpeed = MyGlobal.MaxSpeed;
这少了一个反引用(你没有找到指针,然后解引用它来得到它的位置)。 它也简单,更易于阅读和维护,因为你不需要除了结构创建指针变量。
话虽这么说,我不认为你会看到任何性能差异将是noticable,即使是在一个嵌入式系统。 双方将是非常,非常快的访问时间。
第一个应该是更快,因为它不需要指针废弃。 再说那是基于x86的系统,不知道对别人如此。
在x86第一个将转化为这样的事情
mov eax, [address of MyGlobal.MaxSpeed]
而第二个会是这样的
mov ebx, [address of pMyGlobal]
mov eax, [ebx+sizeof(int)]
在您的嵌入式平台,很可能是该架构以这样的方式优化的,它本质上是一个洗,即使它不是,如果这是在一个非常紧密循环执行,你永远只能看到一对性能的影响。
有您的系统可能更明显的表现领域。
struct dataStruct
{
double first;
double second;
} data;
int main()
{
dataStruct* pData = &data;
data.first = 9.0;
pData->second = 10.0;
}
这是使用VS2008释放模式的组件的输出:
data.first = 9.0;
008D1000 fld qword ptr [__real@4022000000000000 (8D20F0h)]
pData->second = 10.0;
008D1006 xor eax,eax
008D1008 fstp qword ptr [data (8D3378h)]
008D100E fld qword ptr [__real@4024000000000000 (8D20E8h)]
008D1014 fstp qword ptr [data+8 (8D3380h)]
拆解,拆解,拆解...
根据代码的行数你是不是向我们展示它是可能的,如果你的指针是有点静态编译好就会知道,和两个预先计算的地址。 如果你没有对优化那么这整个讨论是静音。 这也取决于你所使用的处理器,既可以根据处理器的单指令执行。 所以我遵循的基本优化步骤:
1)拆开并检查2)的执行时间
正如上面提到的,虽然底线是可能的两个指令,而不是一个成本单个时钟周期,你很可能永远也看不到的情况。 你的编译器和优化选择的质量将会使更多的戏剧性表现的差异不是试图调整一行代码在提升性能的希望。 要切换编译器可以给你10%-20%在任何一个方向,有时更多。 由于可以改变你的优化参数,对犯规转弯一切做出最快的代码,有时-O1性能比-O3更好。
了解什么代码产生怎样的这两条线,以最大限度地从高级语言性能来自编译为不同的处理器,并使用各种编译器拆卸。 更重要的是周围有问题的行代码起到编译器如何优化该段了很大的作用。
使用在这个问题上别人的例子:
typedef struct
{
unsigned int first;
unsigned int second;
} dataStruct;
dataStruct data;
int main()
{
dataStruct *pData = &data;
data.first = 9;
pData->second = 10;
return(0);
}
与海湾合作委员会(不是很大编译)你:
mov r2, #10
mov r1, #9
stmia r3, {r1, r2}
这样的C代码两条线被连接到一个存储,这里的问题是用作试验的例子。 两个独立的功能本来是好一点,但它需要在其周围多了很多代码和指针需要在某些其他内存点,以便优化犯规意识到这是一个静态的全局地址,以测试这一点,你需要通过地址所以编译器(以及GCC)无法弄清楚,它是一个静态地址。
或者没有优化,同样的代码,相同的编译器,指针和直接的没有什么区别。
mov r3, #9
str r3, [r2, #0]
mov r3, #10
str r3, [r2, #4]
这是你希望看到这取决于编译器和处理器,有可能是没有区别的。 对于这款处理器即使测试代码隐藏静态地址从函数指针仍然会归结为两个指令。 如果该值被存储在结构元件中的寄存器已经加载那么这将是一个指令无论哪种方式,指针或直接。
所以回答你的问题不是绝对的...这要看情况。 拆解和测试。
在一般情况下,直接访问该结构会更快,因为它不会需要一个额外的指针引用。 该指针引用意味着它有取指针(在该变量中的东西),负载不管它指向,然后在其上进行操作。
在C,应该没有什么区别,或者微不足道的性能损失。
Ç学生被教导:
pMyGlobal->MaxSpeed == (*pMyGlobal).MaxSpeed
您应该能够使它们在本质上是相同的,比较他们俩说服自己的拆卸,即使你不是一个汇编代码的程序员。
如果你正在寻找一个性能优化,我会看看其他地方。 您将无法保存足够的CPU周期用这种微型的优化。
对于格式上的原因,我更喜欢结构,点符号,尤其是单身,全局打交道时。 我觉得它更简洁的阅读。
直接成员访问速度更快(为指针,你会得到一个指针引用操作更典型)。 虽然我有一个很难的情况下它会是一个问题,性能或其它想象它。