网点运营商成本c/c++

网点运营商成本c/c++,c++,c,dot-operator,C++,C,Dot Operator,我们都知道->vs。speed diff在c/c++中访问成员,但我很难找到简单点运算符实际成本的任何线索 我想象它类似于struct+offset的地址,也假设offset是前面所有成员的所有sizeof-s的总和。这大致正确吗 那么和->谁比起来快多了?两次 看到一些asm,在这里,关于。作为一种指令,我想它有一些魔力 此外,与局部变量相比,速度要慢多少 多谢各位 编辑: 我想我问得不对 要想把事情弄清楚: 通过->vs。我的意思是使用指针访问结构而不是直接成员访问-。 然后我就好奇了:好吧

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

我想象它类似于struct+offset的地址,也假设offset是前面所有成员的所有sizeof-s的总和。这大致正确吗

那么和->谁比起来快多了?两次 看到一些asm,在这里,关于。作为一种指令,我想它有一些魔力

此外,与局部变量相比,速度要慢多少

多谢各位

编辑: 我想我问得不对

要想把事情弄清楚: 通过->vs。我的意思是使用指针访问结构而不是直接成员访问-。 然后我就好奇了:好吧,那点访问本身呢?它花了很多钱。所以我问了这个问题

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


谢谢

任何合适的编译器都会在编译时计算struct字段的地址,因此计算的成本很低。应该是零


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

这取决于大量的事情

这个。运算符可以从比访问局部变量或使用->更便宜到比这两者都更昂贵

这不是一个明智的问题

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

“我们大家”显然不包括我。我不知道有什么特别的区别,特别是在C++之间---vs.…/P> 我想象它类似于struct+offset的地址,也假设offset是前面所有成员的所有sizeof-s的总和。这大致正确吗

那么与->相比,它要快多少?两次看到一些asm,在这里,关于。作为一种指令,我想它有一些魔力

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

这是一个指针,一个方法内的对象都是用这个->有效的前缀,但是C++程序并没有慢到爬行。 显然,如果。应用于引用,则它100%等效于->

另外,它比局部变量慢多少

很难评估。元汇编程序的本质区别在于:访问局部变量的两个asm操作将堆栈上变量的偏移量添加到堆栈指针;访问值vs.三个asm操作通过指针访问对象的属性加载指向该对象的指针;添加偏移量;访问该值。但是由于编译器的优化,这种差异很少明显

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


但是与系统调用的开销相比,字段/属性访问的开销实际上是微不足道的。

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

ptr->variable
应产生与之类似的asm输出

(*ptr).variable // yeah I am using a '.' because it's faster...
因此,你的问题有点荒谬

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

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

现在,我不明白为什么使用->与a相比成本更高。由于它们有效地执行相同的操作,因此在这种情况下,访问权限可能会有所不同:

struct A { int x; };

void function(A& external)
{
  A local;

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

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

但是正如您所注意到的,使用->vs.之间没有区别,区别在于使用存储在堆栈上的局部变量与使用指向外部sup的指针/引用 plied对象,编译器无法对其进行假设


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

完全依赖于实现,C++是一种语言而不是输出。观察特定编译器给出的输出。当然,我们应该清楚,这些信息并不决定任何设计选择,因为你的选择应该是更清洁的,而不是微观优化水平上更快的;我不明白为什么两者之间会有任何区别。运算符和“->运算符”。我能想到的唯一区别是引用的局部性,因此变量更可能位于缓存中,但这不是您所想的。在什么情况下可以通过访问对象访问成员。比通过指针和->执行相同操作更昂贵?在某些情况下,当使用引用/指针时,它可能是等效的,但我不认为在任何情况下它的成本会更高。访问堆上的对象并触发页面错误,->将比..便宜得多。。这就是为什么我说这不是一个明智的问题——答案取决于对象存储的位置,而不是用来访问它的语法。应用于引用,则它100%等效于->。呃,不那么明显。考虑int i;int&j=i;j=5;我想你很难找到一个编译器,它能生成与int I相同的代码;int*const j=&i*j=5;。引用不一定是简单的指针。但是仍然+1,指出这->很好。因为变量在堆栈上而突出并不意味着您可以错过加载指向对象的指针的步骤。@Martin:variable on stack==堆栈上对象的属性,因为没有指向对象的指针。属性的偏移量可以相对于编译时已经存在的堆栈帧的开始计算。@Dummy00001:绝对不是真的。您需要知道变量的地址,而不是属性。您调用的任何方法都需要知道this指针的名称,因此无法避免此步骤。因此,访问局部变量的成本与通过指针访问的成本完全相同,因为您必须获得指向局部变量的指针。试试看。@Martin:因此,通过指针访问局部变量的成本与通过指针访问局部变量的成本完全相同,因为您必须获得指向局部变量的指针。您忘记了指针也必须保存在某个地方。INTA;a、 -通过堆栈帧+堆栈帧内a的偏移量到达a。int*a*a、 -首先必须将a作为局部变量,然后才能访问*a。结构地址和求和的计算/加载如何?@Basilevs问一些有意义的问题如何?这不是一个真正的问题。我想说的是,你对点运算符成本的估计基本上是不正确的:@Basilevs为了声称某人不正确,你必须用一些东西来支持它,否则你的评论基本上是不正确的。@Basilevs:或零。包括x86在内的许多指令集体系结构都包含内存访问指令的偏移寻址模式。这意味着,如果寄存器中有地址,则可以有一条从地址读取+x指令。在这种情况下,偏移基本上是自由的。