2012-05-05 5 views
5

Я написал специальный оператор new и оператор delete для класса MyOrder. Я выделяю память, используя boost :: singleton pool. Вот программа тестирования производительности,Пользовательское распределение с использованием boost Singleton_pool медленнее, чем значение по умолчанию

#include <boost/pool/singleton_pool.hpp> 
#include <boost/progress.hpp> 
#include <iostream> 
#include <new> 
#include <vector> 


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

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

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

    ~MyOrder(){} 

    static void * operator new(size_t size); 
    static void operator delete(void * rawMemory) 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); 
} 

int main() 
{ 
    MyOrder* mo = NULL; 
    std::vector<MyOrder*> v; 
    v.reserve(100000); 

    boost::progress_timer howlong; 
    for(int i = 0; i< 100000; ++i) 
    { 
     mo = new MyOrder("Sanket", "Sharma"); 
     v.push_back(mo); 
    } 

    for (std::vector<MyOrder*>::const_iterator it = v.begin(); it != v.end(); ++it) 
    { 
     delete *it; 
    } 
    return 0; 
} 

Я составил вышеуказанную программу, используя -O2 флаг и побежал на моем Macbook с 2,26 ГГц Intel Core 2 Duo, и потребовалось 0,16 секунды. Затем я прокомментировал строки, где я объявил и определил пользовательский оператор new и оператор delete, перекомпилированный с флагами -O2 и запущенный на том же компьютере, он занял 0.13 секунды.

Выделение и освобождение памяти с помощью singleton_pool для объектов одинакового размера должно ускорить его. Почему это замедляет работу? Или накладные расходы на создание пула, снижающего эффективность, полученную в этой небольшой программе?

Update:

я заменил два станд :: строковые переменные с междунар и двойной и на этот раз запускали две программы с 100000000 (т.е. в 1000 раз до) итераций каждый на 3,0 ГГц AMD Phenom (тм) II X4 945 Процессор. Тот, который использует пользовательское распределение памяти, занимает 3,2 секунды, а тот, который использует выделение по умолчанию, занимает 8,26 секунды. Итак, на этот раз выигрывает пользовательское распределение памяти.

+1

Поскольку вы позаботившись назвать * один * новый обработчик, вероятно, вы должны написать цикл, чтобы попытаться * все * новые обработчики. –

+1

Ваш тест включает в себя распределения по 'std :: string', которые не регулируются вашим пользовательским распределителем, поэтому любые полученные вами результаты вводят в заблуждение _at best_. – Chad

+0

@ Я заменил std :: string на double и int. На этот раз я повторяю их 10000000 раз. Результаты для 1.95s по умолчанию против 2.29s для пользовательских. Все еще распределение/освобождение с использованием пула происходит медленнее. – sank

ответ

5

Я думаю, что ваши цифры не имеют смысла. Если вы только проверили время выполнения один раз, и вы нашли 0.13 против 0.16 секунд, то это совершенно бессмысленно и в нем преобладают накладные расходы.

Вы должны выполнить фрагмент, который хотите протестировать тысячи раз, а затем сравнить данные, чтобы исключить накладные расходы.

Нет на самом деле, что разница 0.03 секунды легко можно объяснить ваш процесс получения потушил и т.д.

 Смежные вопросы

  • Нет связанных вопросов^_^