簡體   English   中英

使用boost :: singleton_pool時處理std :: string / std :: vector成員變量

[英]Dealing with std::string/std::vector member variables while using boost::singleton_pool

我正在編寫一個性能關鍵型應用程序,我在其中創建大量類似類型的對象來下訂單。 我使用boost :: singleton_pool來分配內存。 最后我的班級看起來像這樣。

    class MyOrder{
    std::vector<int> v1_;
    std::vector<double> v2_;

    std::string s1_;
    std::string s2_;

public:
    MyOrder(const std::string &s1, const std::string &s2): s1_(s1), s2_(s2) {}

    ~MyOrder(){}

    static void * operator new(size_t size); 
    static void operator delete(void * rawMemory) throw();
    static void operator delete(void * rawMemory, std::size_t size) throw();

};

struct MyOrderTag{};
typedef boost::singleton_pool<MyOrderTag, sizeof(MyOrder)> MyOrderPool; 

void* MyOrder:: operator new(size_t size)
{
    if (size != sizeof(MyOrder)) 
        return ::operator new(size);

    while(true){
        void * ptr = MyOrderPool::malloc();
        if (ptr != NULL) return ptr;

        std::new_handler globalNewHandler = std::set_new_handler(0);
        std::set_new_handler(globalNewHandler);

        if(globalNewHandler)  globalNewHandler();
        else throw std::bad_alloc();

    }
}

void MyOrder::operator delete(void * rawMemory) throw()
{
    if(rawMemory == 0) return; 
    MyOrderPool::free(rawMemory);
}

void MyOrder::operator delete(void * rawMemory, std::size_t size) throw()
{
    if(rawMemory == 0) return;
    if(size != sizeof(Order)) {
        ::operator delete(rawMemory);
    }
    MyOrderPool::free(rawMemory);
}

我最近發布了一個關於使用boost :: singleton_pool的性能優勢的問題 當我比較boost :: singleton_pool和默認分配器的性能時,我沒有獲得任何性能優勢。 當有人指出我的類有std :: string類型的成員,其分配不受我的自定義分配器的控制時,我刪除了std :: string變量並重新進行了測試。 這次我注意到了相當大的性能提升。

  1. 現在,在我的實際應用中,我無法擺脫時間std :: string和std :: vector的成員變量。 我應該在我的std :: string和std :: vector成員變量中使用boost :: pool_allocator嗎?

  2. boost :: pool_allocator從底層std :: singleton_pool分配內存。 如果不同的成員變量(我的MyOrder類中有多個std :: string / std :: vector類型。重要的是。我還使用了除MyOrder以外的類的池,其中包含std :: string / std :: vector類型作為成員)使用相同的內存池? 如果是這樣,我如何確保他們以某種方式做?

  1. 現在,在我的實際應用中,我無法擺脫時間std :: string和std :: vector的成員變量。 我應該在我的std :: string和std :: vector成員變量中使用boost :: pool_allocator嗎?

我從未研究過boost的那一部分,但是如果你想改變字符串分配內存的位置,你需要在編譯時將不同的分配器傳遞給std::basic_string<> 沒有其他辦法。 但是,您需要注意其缺點:例如,此類字符串將不再分配給std::string (雖然使用c_str()會起作用,但可能會造成很小的性能損失。)

  1. boost :: pool_allocator從底層std :: singleton_pool分配內存。 如果不同的成員變量(我的MyOrder類中有多個std :: string / std :: vector類型。重要的是。我還使用了除MyOrder以外的類的池,其中包含std :: string / std :: vector類型作為成員)使用相同的內存池? 如果是這樣,我如何確保他們以某種方式做?

池的重點是將多個對象放入其中。 如果它只是一個,你就不需要一個游泳池。 所以,是的,您可以將幾個對象放入其中,包括幾個std::string對象的動態內存。

然而,這是否會讓你獲得任何性能提升還有待觀察。 您使用池是因為您有理由認為它比通用分配器更快(而不是使用它,例如,從特定區域分配內存,如共享內存)。 通常這樣的池更快,因為它可以對內部分配的對象的大小進行假設。 這對於你的MyOrder類來說確實如此:它的對象總是具有相同的大小,否則(較大的派生類)你不會在池中分配它們。
這與std::string不同。 使用動態分配字符串類的重點是它適應任何字符串長度。 所需的內存塊大小不同(否則你可能只是char數組)。 我認為池分配器沒有足夠的空間來改進通用分配器。


注意:您的重載operator new()返回調用全局operator new()的結果,但是您的operator delete只是將任何進入該池的free()傳遞給它。 這對我來說似乎很可疑。

在你的類中使用std::string / std::vector的自定義分配器可以工作(假設分配器是正確的) - 但只有性能測試才能看到你是否真正看到它的任何好處。

或者,如果您知道std::string / std::vector將具有上限,則可以在std::array (或正常數組,如果您沒有c ++ 11)周圍實現一個瘦包裝器它是一個替代品。

即使大小是無限制的,如果有一些大小, 大多數值都會小於,你可以擴展基於std::array的實現,通過分配你的池化分配器,如果它們填滿,可以擴展。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM