BOOKS i'm reading |
Real case example of using the undocumented MFC class CFixedAllocContents
IntroductionThis tutorial is a follow up of my tutorial 'Enhance your dynamic memory allocation in C++ with an undocumented MFC class (CFixedAlloc)'. I am proposing to apply
This tutorial will first present a brief presentation of the aspects of Chris Maunder grid control classes that are important for this tutorial. Then I will present the methods that I used to measure the improvement resulting of applying
Presentation of the CGrid controlThis is a prime candidate for applying a fixed allocator optimization. Please consult my
previous tutorial on the topic for a detailed coverage of the positive properties of such an allocator or the
grid control page for an extended coverage on its architecture and its usage. What is important to know for this tutorial is that the grid control consist of an array of
Rows and cells are all dynamically allocated from the heap. It means that for a 64000x8 grid, the control is going to perform 64000
Methods used for performance measurementsFor measuring the time it takes to resize the grid, I have modified the dialog box event handling functions that control the size of the grid in the file GridCtrlDemoDlg.cpp: void CGridCtrlDemoDlg::OnUpdateEditCols() { ... DWORD start = GetTickCount(); TRY { m_Grid.SetColumnCount(m_nCols); } CATCH (CMemoryException, e) { e->ReportError(); return; } END_CATCH DWORD end = GetTickCount(); Trace(_T("Time spent in SetColumnCount(): %d\n"),end-start); ... } void CGridCtrlDemoDlg::OnUpdateEditRows() { ... DWORD start = GetTickCount(); TRY { m_Grid.SetRowCount(m_nRows); } CATCH (CMemoryException, e) { e->ReportError(); return; } END_CATCH DWORD end = GetTickCount(); Trace(_T("Time spent in SetRowCount(): %d\n"),end-start); ... } For measuring the control memory usage I have simply used the task manager 'Processes' tab. Spot the 'GridCtrlDemo.exe' entry in the process list prior resizing the grid and then take note of the new memory usage value after the resizing. CFixedAlloc applicationBefore applying the changes presented in this section, I suggest that you take measurements before so that you can compare the difference.
GridCell.h: #include "GridCellBase.h" #include "fixalloc.h" #define POOL_SIZE 1024 class CGridCell : public CGridCellBase { friend class CGridCtrl; DECLARE_DYNCREATE(CGridCell) DECLARE_FIXED_ALLOC_NOSYNC(CGridCell) ... }; class CGridDefaultCell : public CGridCell { DECLARE_DYNCREATE(CGridDefaultCell) DECLARE_FIXED_ALLOC_NOSYNC(CGridDefaultCell) ... }; GridCell.cpp: IMPLEMENT_FIXED_ALLOC_NOSYNC(CGridCell,POOL_SIZE) IMPLEMENT_FIXED_ALLOC_NOSYNC(CGridDefaultCell,POOL_SIZE) First, note that you will have to update the include directories search path as described in
my previous tutorial. Also, it is very important that you use the macros
For using the GridCtrl.h: class CFixedAllocGridRow : public CTypedPtrArray<CObArray, CGridCellBase*> { DECLARE_FIXED_ALLOC_NOSYNC(CFixedAllocGridRow); }; typedef CFixedAllocGridRow GRID_ROW; GridCtrl.cpp: IMPLEMENT_FIXED_ALLOC_NOSYNC(GRID_ROW,POOL_SIZE) I have chosen the value 1024 for ResultsHere is a table comparing the results obtained with and without the
ConclusionEverything looks too good to be true. There is one
disadvantage of incorporating the proposed optimization. While it is true that the grid resizing will
be blazingly fast and use memory more efficiently, once the fixed allocator has allocated a pool of memory, it will never be released until the end of the program execution. If you are allocating memory for a 64000x16 grid once then you will
use that memory even if you shrink back the grid to a 32x32 grid for the rest of the execution of the program. For some programs, it might be unacceptable. That being said, it is certainly possible to come up with a home-brew fixed size allocator with a little bit more of intelligence. Not too much to lose the benefits of
Before finishing, there are few points that are discussed in my previous tutorial that are worth mentionning again:
Also, my blog is probably the best medium if you would like to provide feedback to this tutorial, you can do so here. Bibliography
|