(*i).member 是不是比 i->member 效率低

Posted

技术标签:

【中文标题】(*i).member 是不是比 i->member 效率低【英文标题】:Is (*i).member less efficient than i->member(*i).member 是否比 i->member 效率低 【发布时间】:2013-04-27 15:43:17 【问题描述】:

拥有

struct Person 
   string name;
;

Person* p = ...

假设没有运算符被重载。


哪个更有效(如果有的话)?

(*p).name 对比 p->name

在我脑后的某个地方,我听到一些铃声响起,* 取消引用运算符可能会创建对象的临时副本;这是真的吗?


这个问题的背景是这样的:

Person& Person::someFunction()
    ...
    return *this;

我开始怀疑,将结果更改为 Person* 并将最后一行更改为简单的 return this 是否会产生任何影响(在性能方面)?

【问题讨论】:

此时您应该更加担心可读性,并且由于-> 是更常见的语法糖,(*i).m 在许多地方都令人不悦。只有当任何分析表明可能存在与此相关的问题时,您才应该开始担心其效率。 我希望编译器产生完全相同的结果。您可以自己回答这个问题,将两个代码编译成汇编器并检查生成的代码。 我问这个问题是因为我描述的背景 - 许多基本运算符通常返回对自我的引用,我经常看到它们返回*this; *p 是一个左值(你可以做*p = something;)。这怎么会创建一个临时对象? @KalamarObliwy 没有这种可能性。内置指针解引用运算符* 返回一个左值,指定指向的对象(您可以将其视为对它的引用)。 【参考方案1】:

没有区别。甚至标准都说两者是等价的,如果有任何编译器不能为两个版本生成相同的二进制文件,那就太糟糕了。

【讨论】:

内置类型和用户自定义的一样吗?? @KalamarObliwy 假设没有运算符重载,是的。 对于标准智能指针(std::unique_ptrstd::shared_ptr),重载的操作符的行为仍然相同。【参考方案2】:

当您返回一个引用时,这与返回一个指针完全相同,指针语义除外。 你传回 sizeof(void*) 元素,而不是 sizeof(yourClass)

所以当你这样做时:

Person& Person::someFunction()
    ...
    return *this;

您返回一个引用,并且该引用具有与指针相同的内在大小,因此没有运行时差异。

同样适用于 (*i).name,但在这种情况下,您将创建一个 l-value,它与引用具有相同的语义(另请参阅 here)

【讨论】:

这是关于回报大小的一个好点。你能解释一下,*p 自己做了什么吗?它的结果是 Person& 或 Person,还是 const Person&? 如果我正确阅读 ***.com/questions/11347111/… 并根据***:en.wikipedia.org/wiki/Value_(computer_science),您会得到一个 l-value,它引用了对象的地址【参考方案3】:

是的,阅读和打字要困难得多,所以使用x->y 比使用(*x).y 好得多 - 但除了打字效率之外,绝对没有区别。编译器仍然需要读取x 的值,然后将偏移量添加到y,无论您使用一种形式还是另一种形式[假设没有涉及覆盖operator->operator* 的有趣对象/类当然,分别]

在引用(*x) 时肯定不会创建额外的对象。指针的值被加载到处理器 [1] 中的寄存器中。就是这样。

返回引用通常更有效,因为它返回指向对象的指针(变相),而不是复制对象。对于大于指针大小的对象,这通常是一个胜利。

[1] 是的,我们可以为没有寄存器的处理器提供 C++ 编译器。我知道我在 1984 年左右看到的 Rank-Xerox 的至少一个处理器,它没有寄存器,它是一个专用的 LiSP 处理器,它只有一个用于 LiSP 对象的堆栈......但它们远非常见在现今世界里。如果有人在没有寄存器的处理器上工作,请不要仅仅因为我没有涵盖该选项而否决我的答案。我试图保持答案简单。

【讨论】:

【参考方案4】:

任何好的编译器都会产生相同的结果。您可以自己回答这个问题,将这两个代码编译成汇编程序并检查生成的代码。

【讨论】:

以上是关于(*i).member 是不是比 i->member 效率低的主要内容,如果未能解决你的问题,请参考以下文章

python数组赋值

Iterator和Iteratable的区别,介绍

(HDU)1219 -- AC Me

洛谷P1428小鱼比可爱

php数组序列化a:1:i:0;s:1:"1" 的详细解释

C++error C2511: overloaded member function 'void (void)' not found in 'class'请大神指教