0

我们都知道 -> vs 。在 c/c++ 中访问成员的速度差异,但我很难找到简单点运算符的实际成本的任何线索。

我想它类似于结构地址 + 偏移量,还假设偏移量是所有先前成员的所有 sizeof-s 的总和。这(大致)正确吗?

然后相比 -> 快得多呢?两次?
(在 SO 上看到了一些 asm,关于 .access 是一条指令,我想它有一些魔力)

另外,与局部变量相比,慢了多少?

谢谢你

编辑:
我猜我没问对。

尝试清理:
通过“-> vs .” 我的意思是“使用指针访问结构”与“直接成员访问”-(链接)。
然后我很好奇:“好吧,点访问本身呢?它确实要花一些钱。” 所以我问了这个问题。

“点运算符成本 c/c++”本身可能是荒谬/无意义/幼稚的问题,但它确实得到了我正在寻找的答案。现在不能说更好。

谢谢

4

4 回答 4

8

我们都知道 -> vs 。在 c/c++ 中访问成员的速度差异,但我很难找到简单点运算符的实际成本的任何线索。

“我们所有人”显然不包括我。我不知道->..

我想它类似于结构地址 + 偏移量,还假设偏移量是所有先前成员的所有 sizeof-s 的总和。这(大致)正确吗?

是的。

那么相比->起来快多少呢?两次?(在 SO 上看到了一些 asm,关于.访问是一条指令,我想它有一些魔力)

两者都->涉及.计算有效地址,这是最昂贵的操作(除了实际的内存访问)。如果指针(在 的左侧->)经常使用(例如),那么它很可能已经被编译器缓存在 CPU 寄存器中,从而有效地否定了和this之间的任何可能差异。->.

好吧,this是一个指针,属于方法内对象的所有内容都有效地以 为前缀this->,但 C++ 程序并没有慢到爬行。

显然,如果.应用于参考,那么它是 100% 等价的->

另外,与局部变量相比,它慢了多少?

很难评价。元汇编程序的本质区别是:两个 asm ops 访问局部变量(将变量在堆栈上的偏移量添加到堆栈指针;访问值)与三个 asm ops 通过指针访问对象的属性(加载指向对象的指针;添加偏移量;访问值)。但是由于编译器优化,这种差异很少被注意到。

通常,局部变量和全局变量之间的区别是突出的:必须计算局部变量/对象属性的地址,而所有全局变量都具有在链接时计算的唯一全局地址。

但是与系统调用的开销相比,字段/属性访问的开销确实可以忽略不计且微不足道。

于 2010-08-09T13:05:18.980 回答
5

任何体面的编译器都会在编译时计算struct字段的地址,因此成本. 应该为零。

换句话说,访问struct字段使用.与访问变量一样昂贵。

于 2010-08-09T12:23:50.947 回答
0

这取决于很多事情。

运算符可以从.比访问局部变量便宜或使用->到比任何一个都贵得多。

这不是一个明智的问题。

于 2010-08-09T12:25:25.267 回答
0

我想说成本的差异不在于操作员本身,而在于访问左侧对象的成本。

ptr->variable

应该产生类似的 asm 输出

(*ptr).variable // yeah I am using a '.' because it's faster...

因此,您的问题有点荒谬。

我想我明白你的意思,所以我会试着回答这个问题。

运营商本身几乎没有成本。它们只涉及计算地址。该地址表示为对象的地址加上偏移量(可能在编译时固定,因此在程序中每个字段都是一个常量)。真正的成本来自实际获取该地址的字节。

现在,我不明白为什么使用 a->和 a会更昂贵,.因为它们有效地做同样的事情,但在这种情况下可能存在访问差异:

struct A { int x; };

void function(A& external)
{
  A local;

  external.x = local.x;
}

在这种情况下,访问external.x成本可能更高,因为它需要访问函数范围之外的内存,因此编译器无法提前知道内存是否已经被提取并放入处理器缓存(或注册)等...

另一方面local.x,由于是本地的并存储在堆栈(或寄存器)上,编译器可能会优化掉代码的获取部分并local.x直接访问。

->但是您注意到使用vs之间没有区别.,区别在于使用局部变量(存储在堆栈中)与使用指向外部提供的对象的指针/引用,编译器无法对此做出假设。

最后,需要注意的是,如果函数是内联的,那么编译器可以在调用者的站点优化它的使用,并在那里有效地使用稍微不同的实现,但无论如何不要尝试内联所有内容:首先编译器可能会忽略你的提示,如果你真的强迫它,你实际上可能会失去性能。

于 2010-08-09T13:45:33.610 回答