2012-05-05 9 views
5

Escribí el operador personalizado new y el operador delete para la clase MyOrder. Estoy asignando memoria usando boost :: singleton pool. Este es el programa para verificar el funcionamiento,Asignación personalizada utilizando boost singleton_pool más lento que el predeterminado

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

I compilado el programa anterior utilizando O2 bandera y corrió en mi MacBook con 2,26 GHz Intel Core 2 Duo y tardó 0.16 segundos. Luego comenté las líneas donde he declarado y definí el operador personalizado new y el operador delete, recompilamos con -O2 flags y corrimos en la misma máquina que tomó 0.13 segundos.

La asignación y desasignación de memoria con singleton_pool para objetos del mismo tamaño debería acelerarla. ¿Por qué lo está haciendo lento? ¿O la sobrecarga de crear un grupo de servidores anula el beneficio de rendimiento obtenido en este pequeño programa?

Actualización:

que sustituyen las dos variables std :: string con un int y un doble y esta vez corrieron los dos programas con 100000000 (es decir, 1000 veces antes) iteraciones cada uno en un 3,0 GHz AMD Phenom (tm) Procesador II X4 945. El que utiliza la asignación de memoria personalizada tarda 3,2 segundos, mientras que el que utiliza la asignación de memoria predeterminada tarda 8,26 segundos. Así que esta vez la asignación de memoria personalizada gana.

+1

Puesto que usted está tomando la molestia de llamar a uno * * nuevo manejador, es probable que debe escribir un bucle para tratar * todos * nuevos controladores. –

+1

Su prueba incluye las asignaciones de 'std :: string' que no se rigen por su asignador personalizado, por lo que cualquier resultado que obtenga es engañoso _at best_. – Chad

+0

@Chad Reemplacé std :: string por un doble y un int. Esta vez los estoy iterando 10000000 veces. Los resultados son 1.95 para el predeterminado frente a 2.29 para el personalizado. Aún la asignación/desasignación que usa el grupo es más lenta. – sank

Respuesta

5

Creo que sus números no tienen sentido. Si solo verificó el tiempo de ejecución una vez, y encontró 0.13 vs 0.16 segundos, eso no tiene sentido y está dominado por la sobrecarga.

Debe ejecutar el fragmento que desea probar miles de veces y luego comparar los datos para descartar la sobrecarga.

No, en serio, esa diferencia 0.03 segundos fácilmente se puede explicar por el proceso de conseguir conmutada a cabo, etc.

Cuestiones relacionadas