Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/161.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何改进作为类成员变量的智能指针的解引用_C++_Reference_C++14_Shared Ptr_Smart Pointers - Fatal编程技术网

C++ 如何改进作为类成员变量的智能指针的解引用

C++ 如何改进作为类成员变量的智能指针的解引用,c++,reference,c++14,shared-ptr,smart-pointers,C++,Reference,C++14,Shared Ptr,Smart Pointers,我的班级结构如下- 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

我的班级结构如下-

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()
ptr
是一个非空的共享指针

缓存对
内部
对象的引用没有任何改进,因为在所有现有实现中,引用都是作为指针实现的。基本上,您只是复制了
shared_ptr
中的指针,并增加了
Outer
对象的大小

除非您能够将
内部
直接缓存为
外部
的成员,或者至少缓存其数据的某个重要子集,否则您几乎无能为力。您必须重新考虑
内部
外部
类的设计,以及是否可以合并它们

需要考虑的另一点是,是否有可能优化代码的内存访问模式。例如,如果有一个
外部
对象的列表,在该列表上调用
计算
,那么如果每个
内部
对象是单独分配的,则对
内部
对象的访问可能是不可预测的。如果这些对象在连续缓冲区中线性分配(例如,在的
向量中,通过使用自定义内存分配器),则可以提高性能


当然,正如其他人所建议的,您应该对代码进行配置,以查看该代码是否实际上是瓶颈,以及是否有任何更改实际上提高了性能。

< P>引用通常是在C++硬件级别上实现的指针,当它不能完全删除时(因为逻辑上它是别名)。从类的主体中删除引用是非常困难的;我不知道有编译器会尝试(在某些情况下可能完全消除类实例除外)

就生成的程序集而言,遵循
内部常量和
共享的\u ptrconst
之间的区别基本上是没有的

现在,您误解了
const
的工作原理
const-InnerPtr
是指向非常量值的常量指针,而
const-Inner&
是对常量值的引用。但我想这不是故意的

现在,一个
Foo&
类似于一个
Foo*const
,因此顶级
const
可能会以某种方式导致一些优化;您不允许更改任何一点的位置。这可能导致编译器能够证明
Foo&
在两位代码中引用同一对象,而不能证明
Foo*
引用同一对象

但是,在您的示例中,您有一个
常量共享\u ptr
,它也有顶级
常量

一般来说,过早优化是万恶之源。但过早悲观也是如此(与优化相反)。跟随智能指针并不是过早的按下初始化,而您的参考优化就是过早优化的一个例子。当你已经确定了性能瓶颈时,你只应该考虑做出这种改变。


老实说,当您从右值共享ptr构建
Outer
类时,您更可能遇到由构造函数中无关引用计数增加引起的问题,而不是您所识别的问题。此外,额外的原子引用计数将是一种扩散性的减速,因为原子操作同步不会导致代码运行时的大部分减速,而是破坏CPU缓存,使程序的其余部分变慢

因此,改变这一点:

explicit Outer(InnerPtr ptr) : ptr_(std::move(ptr)) {} 
消除悲观情绪;现在:

Outer outer( GenerateInnerPtr() );
是否比以前减少了1个引用计数的增加和减少,并且没有其他情况导致更多引用计数的增加/减少。

首先:

过早优化是编程中所有罪恶(或至少大部分)的根源

这句话很重要,因为人们往往错误地理解是什么让程序变慢,什么让程序变快

第二: 让我们假设间接的方法会使程序变慢。那么最大的问题是:你需要间接性吗?你的问题没有明确的答案。原因是生命周期管理还是对象多态性?我强烈地认为,如果你能在脑海中进行这些优化,你就能完全消除间接性

第三: 我认为更重要的是编译器是否能够内联所有的计算函数调用。因此,内部类的定义看起来如何也很重要。这就是为什么总是发布一篇文章的原因之一

第四: 如果您仍然真正关心您的程序的性能配置文件,那么您也可以使用它

更新,第五: 我忘了提到:算法复杂度通常是性能差的更大问题,意思是:你会循环几次吗?你的循环是嵌套的吗?您可以在创建之前或创建时计算它吗?你能缓存值吗

我不确定这是否是最好的解决方案


可能不会。只要您使用一个优化程序,通过引用间接定向与通过共享指针间接定向一样昂贵,因此您不一定要保存任何东西,而您通过使类不可分配来支付费用,并且通过存储两次地址来简单地增大容量。

“我认为这会对性能产生影响”我强烈建议在采取行动之前先测试这个假设。首先对整个程序进行基准测试和概要分析。再次优化顶部两个(或可能三个)瓶颈和工作台/剖面。最多这样做几次,你的表现应该“足够好”。我怀疑你会在优化过程中的任何地方遇到这样的指针解除限制优化
Outer outer( GenerateInnerPtr() );