Ich habe einen benutzerdefinierten Operator new und Operator delete für die Klasse MyOrder geschrieben. Ich reserviere Speicher mit boost::singleton_pool. Hier ist das Programm, das die Leistung testet:
#include
#include
#include
#include
#include
class MyOrder{
std::vector v1_;
std::vector 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 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 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::const_iterator it = v.begin(); it != v.end(); ++it)
{
delete *it;
}
return 0;
}
Ich habe das obige Programm mit dem -O2-Flag kompiliert und auf meinem Macbook mit einem Intel Core 2 Duo mit 2,26 GHz ausgeführt und es dauerte 0,16 Sekunden. Dann habe ich die Zeilen auskommentiert, in denen ich den benutzerdefinierten Operator new und Operator delete deklariert und definiert habe, erneut mit -O2-Flag kompiliert und auf derselben Maschine ausgeführt, dauerte es 0,13 Sekunden.
Das Allozieren und Deallozieren von Speicher für Objekte gleicher Größe mit singleton_pool sollte die Geschwindigkeit erhöhen. Warum verlangsamt es sich? Oder hebt der Overhead des Erstellens eines Pools den Leistungsvorteil in diesem kleinen Programm auf?
Update:
Ich habe die beiden std::string-Variablen durch eine int und eine double ersetzt und diesmal die beiden Programme mit jeweils 100000000 (das heißt, 1000-mal zuvor) Iterationen auf einem 3,0-GHz-AMD-Phenom(tm)-II-X4-945-Prozessor ausgeführt. Die Verwendung der benutzerdefinierten Speicherzuweisung dauert 3,2 Sekunden, während die Verwendung der Standard-Speicherzuweisung 8,26 Sekunden dauert. Diesmal gewinnt die benutzerdefinierte Speicherzuweisung.