简体   繁体   English

C ++中的原始指针管理

[英]Raw Pointer Management in C++

I have a piece of performance critical code. 我有一段性能关键代码。 The class and objects are fairly large, hence, it would be stored as pointers in the STL container. 类和对象相当大,因此,它将作为指针存储在STL容器中。 Problems arise when the pointers to objects need to be stored in multiple different containers based on some logic. 当基于某种逻辑需要将指向对象的指针存储在多个不同的容器中时,就会出现问题。 It is very messy in handling the ownership of the object as I couldn't isolate the ownership of the object to a single containers(which I could just delete from the single container). 处理对象的所有权非常混乱,因为我无法将对象的所有权隔离到单个容器中(我可以从单个容器中删除它)。 Other than using smart pointer (since it is performance critical and smart pointer might affects the performance), what could I do? 除了使用智能指针(由于它对性能至关重要并且智能指针可能会影响性能)之外,我该怎么办?

Thanks. 谢谢。

You are asking for impossible - from one point, you are asking for exceptional performance, such that smart pointers you claim cannot provide, and you also happen to ask for safety and tidiness. 您要求的是不可能的事情-从某一方面讲,您是在要求卓越的性能,以至于您声称无法提供的智能指针,并且您还恰巧要求安全和整洁。 Well, one comes at the cost of another, actually. 好吧,实际上是以一个为代价的。 You could, of course try to write your own shared pointer, which would be more lightweight than boost's, but still provide the basic functionality. 当然,您可以尝试编写自己的共享指针,该共享指针比boost的指针更轻巧,但仍提供基本功能。 Incidentally, have you actually tried boost::shared_ptr? 顺便说一句,您是否实际尝试过 boost :: shared_ptr? Did it actually slow down the performance? 实际上降低了性能吗?

Your question is very awkward: you ask for performance with a messy logic ? 您的问题很尴尬:您是否要求逻辑混乱?

shared_ptr have incredible performance, really, and though you can get better it is probably your best choice: it works. 实际上, shared_ptr性能令人难以置信,尽管您可以变得更好,但这可能是您的最佳选择:它可以工作。

You could look up another Boost smart pointer though: boost::intrusive_ptr . 不过,您可以查找另一个Boost智能指针: boost :: intrusive_ptr

This is done at the cost of foregoing: weak_ptr and in exchange allows to have a single memory allocation for both the counter and the object. 这是以前述代价为代价的: weak_ptr作为交换,允许为计数器和对象都具有单个内存分配。 Packing up the two yields a SMALL increase in performance. 将两者组合在一起,可以显着提高性能。

If you do not have cyclic reference, try and check it out, it might be what you were looking for. 如果您没有循环引用,请尝试将其检出,这可能正是您想要的。

Intrusive smart pointers are typically more efficient than normal smart pointers, yet easier than dumb pointers. 侵入式智能指针通常比普通智能指针更有效,但比哑指针更容易。 For instance, check out boost::intrusive_ptr<T> 例如,检查boost::intrusive_ptr<T>

If the objects don't refer to one another, manual reference counting might be worth trying. 如果对象之间没有相互引用,则可能需要尝试手动引用计数。 There would be more cost when adding to or removing from a list, but no overhead to the actual object access. 添加到列表或从列表中删除时会花费更多,但实际对象访问没有开销。 (This can be painful to diagnose when you get it wrong, so I recommend being careful to get it right.) (如果发现错误,这可能会很痛苦地进行诊断,因此,我建议谨慎处理。)

If there is dead time between operations, consider a sort of garbage collect. 如果两次操作之间有停滞时间,请考虑进行某种垃圾收集。 Maintain the list of all objects (an intrusive list would probably do). 维护所有对象的列表(侵入列表可能会这样做)。 When you have time to spare, cross-reference this against the other lists; 如果您有时间,可以将其与其他列表进行交叉引用。 any objects that aren't in a list can get deleted. 不在列表中的任何对象都可以删除。 You don't need an extra array to do this (just a global counter and a last-seen counter on each object) so it could be reasonably efficient. 您不需要额外的数组来执行此操作(只需在每个对象上使用全局计数器和最后看到的计数器),这样它就可以相当有效。

Another option would be to use a smart pointer that provides access to the underlying pointer. 另一个选择是使用提供对基础指针的访问的智能指针。 If you're trying to avoid the overhead of calling an overloaded operator-> a lot then this might be worth trying. 如果您想避免过多地调用重载的operator->的开销,那么可能值得尝试。 Store the smart pointers in the lists (this does the lifetime management for you) and then when running through the objects you can retrieve the raw pointer for each and operate using that (so you don't incur the overhead of any overloaded operator-> etc.). 将智能指针存储在列表中(这将为您进行生命周期管理),然后在运行对象时,您可以检索每个对象的原始指针并使用该指针进行操作(因此,不会产生任何重载的operator->的开销。等等。)。 For example: 例如:

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
    }
}

This is the sort of approach I prefer personally. 我个人更喜欢这种方法。 Long-term storage gets a smart pointer, short-term storage gets a plain pointer. 长期存储获得智能指针,短期存储获得普通指针。 The object lifetimes are easy to manage, and you don't fall foul of 1,000,000 tiny overheads (more important for keeping the debug build runnable than it is for the release build, but it can easily add to wasted time nonetheless). 对象的生存期易于管理,并且不会造成1,000,000的微小开销(对于保持调试版本的运行性比发布版本的运行更重要,但尽管如此,它很容易浪费时间)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM