2010-11-23 72 views
1

我有一块性能严重的代码。类和对象相当大,因此它将作为指针存储在STL容器中。当指向对象的指针需要根据某种逻辑存储在多个不同的容器中时会出现问题。处理对象的所有权非常麻烦,因为我无法将对象的所有权分离到单个容器(我可以从单个容器中删除它)。除了使用智能指针(因为它是性能关键和智能指针可能会影响性能),我该怎么办?C++中的原始指针管理

谢谢。

+7

尝试智能指针。配置文件来检查它是否有太大的影响。有机会,它不会太多,而且可能比大多数自己的解决方案都要少。 – sje397 2010-11-23 10:25:33

+1

不幸的是,你可以做的事情不多。您需要定义责任,即谁负责拥有您的资源。在我看来,这是C++的一个基本问题,也许是人们转向其他语言的最大原因之一。 – 2010-11-23 10:27:49

+1

您是否勾画了智能指针?还是仅仅是您的猜测? – Simone 2010-11-23 10:28:27

回答

5

你要求的是不可能 - 从某一点来说,你要求卓越的表现,例如你声称不能提供的智能指针,而且你也碰巧要求安全和整洁。那么,其实一个是以另一个为代价的。当然,你可以尝试编写自己的共享指针,它比boost更轻量级,但仍然提供基本功能。顺便说一句,你有没有试过 boost :: shared_ptr? 实际上减慢了性能吗?

+2

关于`shared_ptr`的一点是:最好使用`make_shared`来构建它,它效率更高。 – 2010-11-23 10:32:23

1

你的问题很尴尬:你用一个凌乱的逻辑要求表现吗?

shared_ptr真的有令人难以置信的表现,虽然你可以变得更好,但它可能是你最好的选择:它的工作原理。

虽然您可以查找另一个Boost智能指针:boost::intrusive_ptr

这是以上述成本完成的:weak_ptr,并且交换允许为计数器和对象分配单个存储器。将这两个包装起来会使性能提高很小。

如果您没有循环参考,请尝试检查它,这可能是您正在寻找的。

0

侵入式智能指针通常比普通的智能指针更高效,但比愚蠢指针更容易。例如,检出boost::intrusive_ptr<T>

0

如果对象之间没有引用,手动引用计数可能值得尝试。添加到列表或从列表中删除时会有更多的成本,但实际对象访问没有开销。 (这可能会在诊断错误时很痛苦,所以我建议小心行事。)

如果在操作之间存在死区,请考虑一种垃圾收集。维护所有对象的列表(入侵列表可能会这样做)。当你有时间备用时,与其他名单交叉引用;任何不在列表中的对象都可能被删除。您不需要额外的数组来执行此操作(只是一个全局计数器和每个对象上的最后一个计数器),所以它可能相当有效。

另一种选择是使用智能指针来提供对底层指针的访问。如果你想尽量避免调用超载operator->的开销,那么这可能值得尝试。将智能指针存储在列表中(这会为您提供生命周期管理),然后在运行对象时,您可以检索每个对象的原始指针并使用该指针进行操作(因此不会产生任何超载的开销)。 )。例如:

std::vector<smart_ptr<T> > objects; 

if(!objects.empty()) { 
    smart_ptr<T> *objects_raw=&objects[0]; 
    for(size_t n=objects.size(),i=0;i<n;++i) { 
     T *object=objects_raw[i].get_ptr(); 

     // do stuff 
    } 
} 

这是我个人比较喜欢的方式。长期存储获得一个智能指针,短期存储获得一个简单的指针。对象的生命周期很容易管理,并且不会受到1,000,000个微小开销的影响(对于保持调试版本的可运行性而言,比发布版本更重要,但它很容易增加浪费的时间)。