c++ - 如何改进作为类成员变量的智能指针的取消引用
问题描述
我有以下类结构 -
typedef std::shared_ptr<Inner> InnerPtr;
class Outer {
private:
const InnerPtr ptr_;
public:
Outer(const InnerPtr& ptr) : ptr_(ptr) {}
int calculate(int id) {
return ptr_->calculate_other(id);
}
}
在这里,Outer::calculate()
可能会被调用很多次(以百万为单位)。
由于每次调用Outer::calculate()
dereferences ptr_
,我认为与仅使用对象相比,它会对性能产生影响。
所以我想出了这个-
typedef std::shared_ptr<Inner> InnerPtr;
class Outer {
private:
Inner& obj_; // to reference *ptr_
const InnerPtr ptr_; // still need to hold a copy of smart pointer to ensure obj stays in memory during the lifetime of Outer
public:
Outer(const InnerPtr& ptr) : ptr_(ptr), obj_(*ptr) {}
int calculate(int id) {
return obj.calculate_other(id);
}
}
我不确定这是否是最好的解决方案。我正在寻找改进calculate
功能的建议。
注意:假设ptr
传递给Outer()
的是一个非空共享指针
解决方案
引用通常在 C++ 中作为硬件级别的指针实现,当它不能完全删除时(因为在逻辑上它是一个别名)。从类的主体中删除引用非常困难;我不知道有一个编译器会尝试(除了在某些情况下可能完全消除类实例)。
Inner const&
就生成的程序集而言,遵循 a和 a之间的区别shared_ptr<Inner const>const
基本上没有什么区别。
现在,您误解了如何const
工作;const InnerPtr
是指向非 const 值的 const 指针,const Inner&
而是对 const 值的引用。但我认为这不是故意的。
现在, aFoo&
类似于 a Foo* const
,因此顶层 const
可能会以某种方式导致一些优化;您不得更改任何一点的位置。这可能导致编译器能够证明 aFoo&
在两位代码中引用同一个对象,但无法证明 aFoo*
确实如此。
但是,在您的示例中,您有一个const shared_ptr
,它也有顶级const
。
一般来说,过早的优化是万恶之源。但是过早的悲观化(优化的反面)也是如此。遵循智能指针并不是过早的加压,您的参考优化是过早优化的一个例子。只有当您已经确定存在性能瓶颈时,您才应该考虑进行此类更改。
Outer
老实说,当您从右值共享 ptr构建类时,您更有可能遇到由构造函数中无关引用计数增加引起的问题,而不是您发现的问题。更重要的是,额外的原子引用计数将导致扩散减速,因为原子操作同步不会导致代码运行时的大部分减速,而是会破坏 CPU 缓存并使程序的其余部分慢点。
所以改变这个:
explicit Outer(InnerPtr ptr) : ptr_(std::move(ptr)) {}
消除悲观情绪;现在:
Outer outer( GenerateInnerPtr() );
引用计数的增加和减少比以前少 1,并且没有其他情况导致更多的引用计数增加/减少。
推荐阅读
- r - 如何对一个数据集中的缺失数据进行 wilcoxon 符号秩检验
- django - 您如何控制模型中存储的语言?
- android-source - 如何使用 Android.bp 解决依赖项缺少的变体 arch:common?
- c# - C# - 检查句柄是否处于活动状态
- scala - 如何防范“选项”论点?
- r - 如何解决数据集变量的问题
- java - 我们如何在现实生活中使用 strictfp 方法?
- python - str 到字节对象,以便在 Matlab 中进一步使用
- javascript - Vue/Nuxt 生命周期在 beforecreate 中调用 promise 并在 created 中调用 getter
- android - 未定义的名称“更改按钮”。尝试将名称更正为已定义的名称,或定义名称