我们都知道 - > vs。使用c / c ++访问成员的速度差异,但我很难找到简单点运算符的实际成本的任何线索。
我想象它的结构地址+偏移量,也假设偏移量是所有前面成员的所有sizeof-s的总和。这(大致)是正确的吗?
然后与 - >进行比较谁快得多?两次?
(看过一些asm,这里是关于。访问是一条指令,我猜它有一些魔力)
另外,与局部变量相比,速度有多慢?
谢谢
修改
我想,我没有正确地问它。
试图澄清事情:
通过“ - > vs。”我的意思是“使用指针访问结构”vs“直接成员访问” - (link)
然后我只是好奇:“好吧,那么点访问本身呢?它花费了很多钱。”所以我问了这个问题。
“点算子成本c / c ++”本身可能是荒谬/无意义/天真的问题,但它确实得到了我正在寻找的答案。现在不能说好了。
由于
答案 0 :(得分:8)
我们都知道 - > vs。使用c / c ++访问成员的速度差异,但我很难找到简单点运算符的实际成本的任何线索。
“我们所有人”显然不包括我。我不知道->
与.
之间存在任何显着差异(特别是在C ++中)。
我想象它的结构地址+偏移量,也假设偏移量是所有前面成员的所有sizeof-s的总和。这(大致)是正确的吗?
是
然后与
->
比较快多少?两次? (看过一些asm,在这里,关于.
访问是一条指令,我猜它有一些魔力)
->
和.
都涉及有效地址的计算,这是最昂贵的操作(除了实际的内存访问)。如果经常使用指针(在->
的左侧)(例如this
),那么它很可能已经被CPU寄存器中的编译器缓存,实际上否定了{{1之间的任何可能的差异}和->
。
好吧,.
是一个指针,属于方法内对象的所有内容都有效地以this
为前缀,但C ++程序并没有放慢速度。
显然,如果将this->
应用于引用,则它与.
完全等效。
此外,与局部变量相比,它有多慢?
难以评估。 元汇编程序的本质区别在于:两个asm操作访问局部变量(将堆栈上的变量的偏移量添加到堆栈指针;访问值)与三个asm操作访问属性通过指针获取对象(将指针加载到对象;添加偏移量;访问该值)。但由于编译器的优化,差异很少引人注意。
通常,本地变量和全局变量之间存在差异:必须计算局部变量/对象属性的地址,而所有全局变量都具有在链接时计算的唯一全局地址。
但是,与例如字段/属性访问相比,字段/属性访问的开销实际上可以忽略不计。系统调用的开销。
答案 1 :(得分:5)
任何体面的编译器都会在编译时计算struct
字段的地址,因此.
的成本应为零。
换句话说,使用struct
访问.
字段与访问变量一样昂贵。
答案 2 :(得分:0)
这取决于很多东西。
.
运算符可以比访问本地变量或使用->
更便宜,而不是比任何一个更加昂贵。
这不是一个明智的问题。
答案 3 :(得分:0)
我想说成本的差异不在于运营商本身,而在于访问左侧对象的成本。
ptr->variable
应该产生与
类似的asm输出(*ptr).variable // yeah I am using a '.' because it's faster...
因此,你的问题实际上是荒谬的。
我想我明白你的意思,所以我会尝试回答这个问题。
运营商本身几乎是无成本的。它们只涉及计算地址。该地址表示为对象的地址加上一个偏移量(可能在编译时固定,因此在每个字段的程序中都是常量)。实际成本来自实际获取此地址的字节。
现在,我不明白为什么使用->
与.
成本会更高,因为他们有效地做同样的事情,虽然在这种情况下可能会有不同的访问权限:
struct A { int x; };
void function(A& external)
{
A local;
external.x = local.x;
}
在这种情况下,访问external.x
可能会更加昂贵,因为它需要访问函数范围之外的内存,因此编译器无法事先知道内存是否已经被提取并且放入处理器缓存(或寄存器)等......
另一方面,local.x
是本地的并存储在堆栈(或寄存器)中,编译器可以优化代码的获取部分并直接访问local.x
。
但正如您所注意到使用->
与.
之间没有区别,区别在于使用局部变量(存储在堆栈中)与使用指向外部提供的对象的引用,编译器无法做出假设。
最后,重要的是要注意,如果函数是内联的,那么编译器可以优化它在调用者站点的使用并有效地使用稍微不同的实现,但不要试图内联所有内容:首先是编译器可能会忽略你的提示,如果你真的强迫它,你实际上可能会失去性能。