性能:指针在C++中取消引用
Performance: Pointer dereferencing in C++
每次我遍历类中的数组(通过指针访问该数组(时,我都会问自己同样的问题:
每次迭代是否通过取消引用指针产生开销?取消引用链加起来吗? 例如:
ClassA *a = new ClassA();
ClassB *b = new ClassB();
for( int i = 0; i < 10; i++){
a->b->array[i].foo();
}
如果我不得不猜测,我会说这涉及 20 个取消引用步骤,每个指针一个,10 次迭代。 但我也可以想象,它减少到 10 个,因为链接指针由编译器转换为单个指针。我什至可以想象,由于一些缓存伏都教或其他东西,它被减少到 1。
有人可以告诉,也许向我解释一下,这在性能方面是如何表现的吗?真的很感激!
顺便说一句,我知道这里已经回答了类似的问题,但我无法推断出这个特定主题的答案。所以请不要责怪我再次提出这个话题。
这实际上取决于编译器(尤其是优化器(想要如何生成代码。 在 as-if 规则下,只要用户无法分辨出程序外部行为的差异,编译器就可以做任何它想做的事情,现代编译器就可以在他们应用的优化方面变得非常聪明。
在实践中,我认为最现代的优化器只有在无法判断 foo(( 内部发生了什么时才无法优化循环——特别是,如果他们不能保证 foo(( 的实现不会改变a
或b
的值,那么他们将被迫生成代码,为每个循环迭代执行单独的a
和b
取消引用, 只是为了确保即使a
或b
的价值观发生变化,也会发生正确的事情。
如果您不介意阅读一些汇编代码,您可以自己找出会发生什么 - 只需将程序编译为汇编,并启用优化(例如g++ -O3 -S mytest.cpp
(,并读取生成的 mytest。S 文件以查看编译器执行的操作。 尝试使用在同一文件中实现的 foo(((这样编译器肯定可以看到 foo(( 的内容(和在不同的文件中实现的 foo(这样编译器可能不得不将 foo(( 视为"黑匣子"(,看看这有什么区别。
你可以确保通过做这样的事情来摆脱一些取消引用:
// create a pointer to the b class outside of the loop
ClassB * bptr = a->b;
// use the pointer inside the loop
for( int i = 0; i < 10; i++){
bptr->array[i].foo();
}
我希望有1 次内存访问,因为 a 和 a->b 在循环中不会改变,所以没有必要再次获取它们。此外,i的所有值对于a->b->array[i]都是已知的,因此可以预取。
- C++取消引用指针.为什么会发生变化
- 使用取消引用的指针的多态性会产生意外的结果.为什么?
- 取消引用运算符不能重载
- 在他自己的方法中,有可能将一个对象取消引用到另一个对象吗
- C++ 关于指针取消引用的技术问题
- 没有取消引用/解包对象的标准方法?
- 列表 iter 不取消引用 使用列表进行插入排序
- 在这个函数中是有缺陷的,因为取消引用 null 是无效的,所以我想更改代码
- 取消引用结束指针到数组类型的一个
- 取消引用向量时出现问题
- 取消引用指向整数的指针时获得不同的结果
- C++:取消引用十六进制值,有点语法问题
- C/C++ 取消引用错误:在空检查之前取消引用
- 取消引用后C++空测试
- 立即取消引用unique_ptr
- 如何在不使用临时变量的情况下取消引用返回指针的函数的返回值?
- 取消引用 void 指针以将值分配给结构
- boost_multi_index迭代器取消引用给出常量
- 矢量迭代器不能与 std::shared_ptr<> 取消引用
- C++我们可以取消引用此指针吗?如果是这样,那么如何,如果不是,那为什么?