I created two smart pointer classes last night. I also tested them, but I think I'm doing something wrong (mine seems to be faster than the regular array allocation/deallocation.) I ran a test, allocating 100000 of my Interface class (a class wrapping an integer.) I averaged the results:
DEFAULT:
157
156
156
156
156
-----
156.2
DFTLIB:
140
125
125
125
125
---
128
I don't really understand how this is possible since my class uses the default new/delete and everything. Here's my test code:
// This is my test class. I also tried it with several other variables inside of it.)
class Interface
{
public:
int integer;
};
//------------------------------------------------------------------------
// WinMain()
//------------------------------------------------------------------------
int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
//------------------------------------------------------------------------
// Memory leak detector
//------------------------------------------------------------------------
_CrtSetDbgFlag(_CRTDBG_LEAK_CHECK_DF | _CRTDBG_ALLOC_MEM_DF);
_CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE);
_CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);
//------------------------------------------------------------------------
// Profiler variable
//------------------------------------------------------------------------
unsigned int nStart = GetTickCount();
//------------------------------------------------------------------------
// Test of default alloc/deallocation
//------------------------------------------------------------------------
/*std::vector<Interface*> Vector;
for(unsigned int nIndex = 0; nIndex < 100000; ++nIndex)
{
Interface* pInt = new Interface;
Vector.push_back(pInt);
}
for(nIndex = 0; nIndex < 100000; ++nIndex)
{
Interface* pInt = Vector.at(nIndex);
delete pInt;
}
Vector.clear();*/
//------------------------------------------------------------------------
// Test of dftlib::SmartPtr alloc/deallocation.
//------------------------------------------------------------------------
std::vector< dftlib::SmartPtr<Interface>*> Vector;
Vector.reserve(100000);
for(unsigned int nIndex = 0; nIndex < 100000; ++nIndex)
{
dftlib::SmartPtr<Interface> SmtPtr;
SmtPtr.Assign(new Interface);
Vector.push_back(&SmtPtr);
}
for(nIndex = 0; nIndex < 100000; ++nIndex)
{
dftlib::SmartPtr<Interface>** ppInt = &Vector.at(nIndex);
(*ppInt)->Release();
}
Vector.clear();
//------------------------------------------------------------------------
// End of profiler
//------------------------------------------------------------------------
unsigned int nEnd = GetTickCount();
unsigned int nDif = nEnd - nStart;
char Msg[16];
itoa(nDif, Msg, 10);
MessageBox(0, Msg, "Profile", MB_OK);
return 0;
}
And my SmartPtr and ComSmartPtr classes:
//--------------------------------------------------------------------------
// This code is part of my(Donald Beals) personal codebase. If you use part
// of it (either in your freeware/shareware/commercial/codebase/library
// please give me credit. I spent a lot of time on it. Thanks!
//--------------------------------------------------------------------------
#ifndef _dftlib_SmartPointers_h_
#define _dftlib_SmartPointers_h_
//--------------------------------------------------------------------------
// Header files
//--------------------------------------------------------------------------
//--------------------------------------------------------------------------
// Start of the dftlib namespace
//--------------------------------------------------------------------------
namespace dftlib
{
//--------------------------------------------------------------------------
// Name: SmartPtr
// Info: Maintains the lifecycle of a pointer.
// Date: 8/18/2005
// Author: Donald Beals (Programmer16)
//--------------------------------------------------------------------------
template <typename PTRTYPE> class SmartPtr
{
PTRTYPE* m_pObject;
public:
SmartPtr()
{
m_pObject = 0;
}
SmartPtr(PTRTYPE* pObj)
{
m_pObject = pObj;
}
~SmartPtr()
{
Release();
}
PTRTYPE* Assign(PTRTYPE* pObj)
{
m_pObject = pObj;
return m_pObject;
}
bool IsValid() const
{
return m_pObject != 0;
}
void Release()
{
if(m_pObject)
{
delete m_pObject;
m_pObject = 0;
}
}
PTRTYPE* GetObject()
{
return m_pObject;
}
PTRTYPE** GetObjectPtr()
{
return &m_pObject;
}
PTRTYPE* operator ->()
{
return m_pObject;
}
PTRTYPE* operator =(PTRTYPE* pObj)
{
m_pObject = pObj;
return m_pObject;
}
};
//--------------------------------------------------------------------------
// Name: ComSmtPtr
// Info: Maintains the lifecycle of a COM interface.
// Date: 8/18/2005
// Author: Donald Beals (Programmer16)
//--------------------------------------------------------------------------
template <typename PTRTYPE> class ComSmtPtr
{
PTRTYPE m_pObject;
public:
ComSmtPtr()
{
m_pObject = 0;
}
ComSmtPtr(PTRTYPE pObj)
{
m_pObject = pObj;
}
~ComSmtPtr()
{
Release();
}
PTRTYPE Assign(PTRTYPE pObj)
{
m_pObject = pObj;
return m_pObject;
}
bool IsValid() const
{
return m_pObject != 0;
}
void Release()
{
if(m_pObject)
{
m_pObject->Release();
m_pObject = 0;
}
}
PTRTYPE GetObject()
{
return m_pObject;
}
PTRTYPE* GetObjectPtr()
{
return &m_pObject;
}
PTRTYPE operator ->()
{
return m_pObject;
}
PTRTYPE operator =(PTRTYPE pObj)
{
m_pObject = pObj;
return m_pObject;
}
PTRTYPE operator[](unsigned int nIndex)
{
return m_pObject[nIndex];
}
};
}
//--------------------------------------------------------------------------
// End of the dftlib namespace
//--------------------------------------------------------------------------
#endif
Any ideas? Any suggestions?
Thanks!