分类:
2008-10-13 16:09:05
ShowTime
//////////////////
// ShowTime displays diagnostics that tell how long an operation took.
// To use, instantiate a ShowTime object at the top of the code block
// you want to clock. If you create a PerfLog, ShowTime will use it.
//
// // in some block of code:
// {
//
ShowTime("time for operation X is");
// // do
operation X
// }
//
class ShowTime {
protected:
LPCTSTR msg;
// display message
clock_t start;
// start time
clock_t end;
// end time
// convert clock ticks to milliseconds
static long msec(clock_t clocktime)
{
return (long)(clocktime *
CLOCKS_PER_SEC / 1000);
}
public:
// ctor: save message, record start time.
ShowTime(LPCTSTR m)
{
msg = m;
start = msec(clock());
}
// dtor: record end time and log results.
~ShowTime()
{
end = msec(clock());
TCHAR buf[512];
_snprintf(buf, 512, _T(" %s: %d msec\n"),
msg, end-start);
PerfLog::Write(buf);
}
};
//////////////////////////////////////////////////////////////// // MSDN Magazine — June 2004 // If this code works, it was written by Paul DiLascia. // If not, I don't know who wrote it. // Compiles with Visual Studio .NET 2003 on Windows XP. Tab size=3. // #include "StdAfx.h" #include "PerfTest.h" #include "Doc.h" #include "ShowTime.h" ••• const BIGNUMALLOC = 20000; // allocate this many objects PerfLog mylog(_T("PerfTest.log")); // open log file // Typical fixed-length record object. class CMyRecord : public CObject { protected: CMyRecord* next; // next record in list TCHAR name[64]; int num; BOOL flag; friend class CMyDoc; public: CMyRecord() { } CMyRecord(int i) { InitRec(i); } void InitRec(int i) { _snprintf(name, 64, _T("rec %d"),i); num = i; flag = TRUE; } virtual void Serialize(CArchive& ar); DECLARE_SERIAL(CMyRecord) }; IMPLEMENT_SERIAL(CMyRecord, CObject, 1) // Serialize one record: write/read string and other data. void CMyRecord::Serialize(CArchive& ar) { if (ar.IsStoring()) { ar.WriteString(name); ar.WriteString(_T("\n")); // don't forget! ar << num << flag; } else { ar.ReadString(name,countof(name)); ar >> num >> flag; } } // Serialize document. This fn serializes each record list array using a // different technique to illustrate the performance of each. void CMyDoc::Serialize(CArchive& ar) { CString msg; msg.Format(_T("CMyDoc::Serialize: %s\n"), ar.IsStoring() ? _T("Write") : _T("Read")); PerfLog::Write(msg); CFile& file = *ar.GetFile(); { // Method 1: Serialize record list the vanilla MFC way (CObList) ShowFileUsed fs(file); ShowTime st(_T("M1: Serializing CObList")); m_recObList.Serialize(ar); } { // Method 2: Serialize individual records (no CObList/list cell) ShowFileUsed fs(file, _T("Total size")); ShowTime st(_T("M2: Serializing individual records")); if (ar.IsStoring()) { ar << m_nRecList; } else { ar >> m_nRecList; // read number of records AllocateRecordsIndividual(m_nRecList); // allocate them // (link too) } for (CMyRecord* prec=m_pRecList; prec; prec=prec->next) { prec->Serialize(ar); } } { // Method 3: Read/write all records as single memory block ShowFileUsed fs(file, _T("Total size")); ShowTime st(_T("M3: Serializing bulk array")); if (ar.IsStoring()) { ar << m_nArray; ar.Write(m_pArray,m_nArray*sizeof(CMyRecord)); } else { ar >> m_nArray; AllocateRecordsBulk(m_nArray); ar.Read(m_pArray,m_nArray*sizeof(CMyRecord)); LinkRecords(m_pArray, m_nArray); } TRACE(_T("len=%d\n"),m_nArray); } } // Create new document: allocate three large record arrays using the three // different methods described above. BOOL CMyDoc::OnNewDocument() { PerfLog::Write(_T("CMyDoc::OnNewDocument\n")); VERIFY(CDocument::OnNewDocument()); { ShowTime st(_T("M1: Allocating for CObList")); AllocateRecordsObList(BIGNUMALLOC); } { ShowTime st(_T("M2: Allocating individual records")); AllocateRecordsIndividual(BIGNUMALLOC); } { ShowTime st(_T("M3: Allocating bulk array")); AllocateRecordsBulk(BIGNUMALLOC); LinkRecords(m_pArray, m_nArray); } return TRUE; } // Allocate records using Method 1: MFC CObjList void CMyDoc::AllocateRecordsObList(int nrec) { for (int i=0; inext = rec; } else { m_pRecList = rec; } prev = rec; } prev->next = NULL; m_nRecList = nrec; } // Allocate records using Method 3: allocate array as one memory block. void CMyDoc::AllocateRecordsBulk(int nrec) { m_pArray = new CMyRecord[nrec]; ASSERT(m_pArray); for (int i=0; i 1) { for (int i=0; i
Log
// Start PerfTest program. This is an MFC SDI app, so MFC creates a new // doc. Program allocates 20,000 records using 3 different methods. CMyDoc::OnNewDocument M1: Allocating for CObList: 130 msec M2: Allocating individual records: 90 msec M3: Allocating bulk array: 70 msec // Save the file (write test). CMyDoc::Serialize: Write M1: Serializing CObList: 200 msec file size = 577457 bytes M2: Serializing individual records: 60 msec Total size = 536514 bytes M3: Serializing bulk array: 61 msec Total size = 2879488 bytes // Open the same file (read test). MFC called DeleteContents first. CMyDoc::DeleteContents M1: Delete CObList: 80 msec M2: Delete individual records: 51 msec M3: Delete bulk array: 10 msec CMyDoc::Serialize: Read M1: Serializing CObList: 240 msec file size = 581553 bytes M2: Serializing individual records: 170 msec Total size = 536514 bytes M3: Serializing bulk array: 90 msec Total size = 2877516 bytes // Quit the app. This calls DeleteContents again. CMyDoc::DeleteContents M1: Delete CObList: 100 msec M2: Delete individual records: 50 msec M3: Delete bulk array: 10 msec
--------------------next---------------------