美文网首页Exceptional C++
【Exceptional C++(16)】Fast Pimpl技

【Exceptional C++(16)】Fast Pimpl技

作者: downdemo | 来源:发表于2018-01-30 09:51 被阅读23次
    • malloc()和new()调用开销很大,下面代码最初在class Y中设计了一个类型X的成员
    // file y.h
    #include "x.h"
    class Y {
        ...
        X x_;
    };
    // file y.cpp
    Y::Y() {}
    
    • 这个class Y的声明需要X的声明可见(从x.h中),为避免这个条件改写为
    // file y.h
    class X;
    class Y {
        ...
        X* px_;
    };
    // file y.cpp
    #include "x.h"
    Y::Y() : px_(new X) {}
    Y::~Y() { delete px_; px_ = 0; }
    
    • 这很好地隐藏了X,但Y被广泛使用时动态内存分配开销降低了性能。隐藏X的动机是避免Y的用户必须知道X,为了消除这种依赖,通常使用pimp方法,但pimpl由于为X的对象分配内存也会导致性能下降。解决方法是Fast Pimpl,使用一个高效的Pimpl,也就是有自己的operator new的pimpl类
    // file y.h
    class YImpl;
    class Y {
        ...
        YImpl* pimpl_;
    };
    // file y.cpp
    #include "x.h"
    struct YImpl {
        ... // private stuff here
        void* operator new(size_t) { ... }
        void operator delete(void*) { ... }
    };
    Y::Y() : pimpl_(new YImpl) {}
    Y::~Y() { delete pimpl_; pimpl_ = 0; }
    
    • 讨论可用性,一个将它们放入一个固定尺寸内存分配器模板中的技巧如下
    template<size_t S>
    class FixedAllocator {
    public:
        void* Allocate(...);
        void Deallocate(void*);
    private:
        // implemented using static?
    };
    
    • 因为私有细节很可能用static实现,因此问题是Deallocate是否被一个static对象的析构函数调用,也许更安全的方法是使用single模式,为每个被请求的尺寸使用一个独立链表,并用一个唯一对象管理这些链表
    class FixedAllocator {
    public:
        static FixedAllocator* Instance();
        void* Allocate(size_t);
        void Deallocate(void*);
    private:
        // singleton implementation
    };
    // 用一个辅助基类封装调用
    struct FastPimpl {
        void* operator new(size_t s) {
            return FixedAllocator::Instance()->Allocate(s);
        }
        void operator delete(void* p) {
            FixedAllocator::Instance()->Deallocate(p);
        }
    };
    // 现在可以很容易地写出任意的Fast Pimpl
    struct YImpl : FastPimpl {
        ... // private stuff here
    };
    
    • 但不要乱用Fast Pimpl,虽然得到了最佳内存分配速度,但维护这些独立链表将导致空间性能小将,因为这会有更多内存碎片,只有在使用了profiler剖析性能并证明需要性能优化后才使用此方法

    相关文章

      网友评论

        本文标题:【Exceptional C++(16)】Fast Pimpl技

        本文链接:https://www.haomeiwen.com/subject/cwyqzxtx.html