首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >指针和性能含义?

指针和性能含义?
EN

Stack Overflow用户
提问于 2012-05-28 21:28:27
回答 6查看 359关注 1票数 5

使用指针时是否会影响性能?

避免使用指针更好吗?如果是,在什么情况下?显然,它们和引用一起有助于减少数据复制。我假设如果指向的数据类型很小,那么对指针的需求就会更小。相反,通过指针传递大对象更好,因为指针的开销比复制对象的开销小。

我还想知道在参数/参数之外的其他领域中的指针?

在这种性能上下文中,引用通常比指针更好吗?

我意识到我正在接近微优化的“脏”话题,但我正在编写一个非常关注延迟的应用程序。

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2012-05-28 21:53:39

我知道性能可能很重要,但语义更重要:快速和错误是没有用的。

使用指针或引用具有语义含义,例如共享:

代码语言:javascript
复制
void foo(A& a) {
    a.a = 1;
    if (a.b != 0) { throw ... }
    a.b = 0;
}

a.b == 0的情况下,a的第一个字段已经更改,但第二个字段没有更改。

此外,这样的共享可能会产生潜在的别名:

代码语言:javascript
复制
void foo(struct A a, struct A b);

void foo(struct A* a, struct A* b);

在第一种情况下,这两种结构必然是不同的,但在后一种情况下则不是。这种可能的别名可能会阻止优化。

首先关注语义。一旦你得到了正确的结果,你就可以调整和测量在你的特定情况下的效果。

票数 7
EN

Stack Overflow用户

发布于 2012-05-28 21:36:56

在这种性能上下文中,引用通常比指针更好吗?

是的,在可以的时候使用引用,在必要的时候使用指针。在性能方面,它们是相同的。

通过引用或指针传递大结构通常会更好,以防止额外的复制,是的。

通过指针或引用访问变量或对象可能与直接访问它一样快。这种效率的原因在于微处理器的构造方式。在函数中声明的所有非静态变量和对象都存储在堆栈中,并且实际上是相对于堆栈指针进行寻址的。同样,类中声明的所有非静态变量和对象都是通过隐式指针访问的,在C++中称为“this”。因此,我们可以得出结论,结构良好的C++程序中的大多数变量实际上都是通过指针以某种方式访问的。因此,微处理器必须设计成使指针高效,这就是它们的本质。

虽然有一些的缺点,但它们同时适用于指针和引用:

但是,使用指针和引用也有缺点。最重要的是,它需要一个额外的寄存器来保存指针或引用的值。寄存器是一种稀缺资源,尤其是在32位模式下。如果没有足够的寄存器,那么每次使用指针时都必须从内存中加载,这会使程序变慢。另一个缺点是,在变量指向的时间可以被访问的几个时钟周期之前,需要指针的值。

here is the source。如果你问这个问题,我想你会发现它是一个很好的读物。

让我们看一些代码:

代码语言:javascript
复制
   int x = 0;
00412E0E  mov         dword ptr [x],0 
   foo(x);
00412E15  lea         eax,[x] 
00412E18  push        eax  
00412E19  call        foo (4111C2h) 
00412E1E  add         esp,4 
   foo(&x);
00412E21  lea         eax,[x] 
00412E24  push        eax  
00412E25  call        foo (4111BDh) 
00412E2A  add         esp,4 

调用函数时没有区别。

代码语言:javascript
复制
void foo (int& x)
{
00411370  push        ebp  
00411371  mov         ebp,esp 
00411373  sub         esp,0C0h 
00411379  push        ebx  
0041137A  push        esi  
0041137B  push        edi  
0041137C  lea         edi,[ebp-0C0h] 
00411382  mov         ecx,30h 
00411387  mov         eax,0CCCCCCCCh 
0041138C  rep stos    dword ptr es:[edi] 
   x = 3;
0041138E  mov         eax,dword ptr [x] 
00411391  mov         dword ptr [eax],3 
}

void foo (int* x)
{
004117A0  push        ebp  
004117A1  mov         ebp,esp 
004117A3  sub         esp,0C0h 
004117A9  push        ebx  
004117AA  push        esi  
004117AB  push        edi  
004117AC  lea         edi,[ebp-0C0h] 
004117B2  mov         ecx,30h 
004117B7  mov         eax,0CCCCCCCCh 
004117BC  rep stos    dword ptr es:[edi] 
   *x = 3;
004117BE  mov         eax,dword ptr [x] 
004117C1  mov         dword ptr [eax],3 
}

函数内部没有差别。

票数 4
EN

Stack Overflow用户

发布于 2012-05-28 21:36:36

通过指针访问数据比直接访问数据要慢一点,但取消引用操作非常快,这通常不是什么大问题,除非您正在执行一些非常具体的重复数字处理任务。

关于传递大对象和小对象的指针,你是完全正确的。例如,int*和int的大小可能相同,具体取决于不同的实现。

在性能方面,引用和指针通常是相同的。但是,如果您习惯于执行const Foo&而不是Foo*,编译器通常可以更好地优化您的代码。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10785471

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档