使用指针时是否会影响性能?
避免使用指针更好吗?如果是,在什么情况下?显然,它们和引用一起有助于减少数据复制。我假设如果指向的数据类型很小,那么对指针的需求就会更小。相反,通过指针传递大对象更好,因为指针的开销比复制对象的开销小。
我还想知道在参数/参数之外的其他领域中的指针?
在这种性能上下文中,引用通常比指针更好吗?
我意识到我正在接近微优化的“脏”话题,但我正在编写一个非常关注延迟的应用程序。
发布于 2012-05-28 21:53:39
我知道性能可能很重要,但语义更重要:快速和错误是没有用的。
使用指针或引用具有语义含义,例如共享:
void foo(A& a) {
a.a = 1;
if (a.b != 0) { throw ... }
a.b = 0;
}在a.b == 0的情况下,a的第一个字段已经更改,但第二个字段没有更改。
此外,这样的共享可能会产生潜在的别名:
void foo(struct A a, struct A b);
void foo(struct A* a, struct A* b);在第一种情况下,这两种结构必然是不同的,但在后一种情况下则不是。这种可能的别名可能会阻止优化。
首先关注语义。一旦你得到了正确的结果,你就可以调整和测量在你的特定情况下的效果。
发布于 2012-05-28 21:36:56
在这种性能上下文中,引用通常比指针更好吗?
?
是的,在可以的时候使用引用,在必要的时候使用指针。在性能方面,它们是相同的。
通过引用或指针传递大结构通常会更好,以防止额外的复制,是的。
通过指针或引用访问变量或对象可能与直接访问它一样快。这种效率的原因在于微处理器的构造方式。在函数中声明的所有非静态变量和对象都存储在堆栈中,并且实际上是相对于堆栈指针进行寻址的。同样,类中声明的所有非静态变量和对象都是通过隐式指针访问的,在C++中称为“this”。因此,我们可以得出结论,结构良好的C++程序中的大多数变量实际上都是通过指针以某种方式访问的。因此,微处理器必须设计成使指针高效,这就是它们的本质。
虽然有一些的缺点,但它们同时适用于指针和引用:
但是,使用指针和引用也有缺点。最重要的是,它需要一个额外的寄存器来保存指针或引用的值。寄存器是一种稀缺资源,尤其是在32位模式下。如果没有足够的寄存器,那么每次使用指针时都必须从内存中加载,这会使程序变慢。另一个缺点是,在变量指向的时间可以被访问的几个时钟周期之前,需要指针的值。
和here is the source。如果你问这个问题,我想你会发现它是一个很好的读物。
让我们看一些代码:
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 调用函数时没有区别。
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
}函数内部没有差别。
发布于 2012-05-28 21:36:36
通过指针访问数据比直接访问数据要慢一点,但取消引用操作非常快,这通常不是什么大问题,除非您正在执行一些非常具体的重复数字处理任务。
关于传递大对象和小对象的指针,你是完全正确的。例如,int*和int的大小可能相同,具体取决于不同的实现。
在性能方面,引用和指针通常是相同的。但是,如果您习惯于执行const Foo&而不是Foo*,编译器通常可以更好地优化您的代码。
https://stackoverflow.com/questions/10785471
复制相似问题