Re: CPtrArray Performance
- From: Joseph M. Newcomer <newcomer@xxxxxxxxxxxx>
- Date: Tue, 28 Jun 2005 12:00:50 -0400
CPtrArray has approximately the same performance as an ordinary array. It is true that it
supports bounds-checks, but that should not represent a major overhead.
The issue is often now how many records, but how many memory fragments are involved, and
the impact of these on paging. While you gave the processor speed, you did not give the
memory size, nor did you say anything about the actual structure of those 5000 items. (One
of my constant themes in my courses are "never worry about code size; it is irrelevant.
But data size can kill you"). If the 5000 items are large, then 5000 1K items represent
5MB of storage. But if the elements consist of CStrings or other pointer-referenced data,
those 5000 elements could represent 20,000 fragments of data if there were only four
pointers per item. Now if statistics are against you, those fragments could be distributed
across 10,000 pages (two objects per page on the average), or 40MB of real memory. This
leads to issues such as paging traffic, which can cost you six orders of magnitude
performance (approximate rule: L1 cache hit costs you 0 cpu cycles; L2 cache hit 1 or 2
cpu cycles [full-speed (Xeon) or half-speed (Celeron) cache], L2 miss costs you 20 cpu
cycles, and page fault costs you 20,000,000 cpu cycles. With high-performance machines
these numbers can double for L2 miss and page fault). So if you generate lots of page
faults you will see a serious performance degradation. This is the sort of place where
performance matters, and spending time optimizing against page faults for large data
structures is often time well spent.
Declaring an ordinary C array will probably not change the picture very much. Note that if
you have complex structures with substructure (e.g., CString or other objects requiring
destructors) that the cost could be in the number of destructor calls. Also note that
freeing storage up could be a performance issue. Back in the days when I wrote storage
allocators for a living, we would do things like single-instruction-step through the
allocator and deallocator looking for how to optimize the execution paths. You get an
insight about this after watching a few thousand instructions go by; we certainly had one
of the fastest allocators around, probably not exceeded in performance until the mid-1990s
except for others like us who spent a lot of time writing really high-performance heap
managers.
Also, are you measuring debug or optimized code? Debug code has MASSIVE overheads (for
example, function entry time can swamp function execution time by an order of magnitude in
the debug builds). If you are not measuring release code, you are not measuring anything
meaningful. In some cases, functions in release mode compile inline into a few
instructures whereas in debug mode they compile into sequences involving such tasks as
initializing the local variables to 0xccccccccc and checking for stack overflow, which
can completely swamp the actual function execution. And that means every destructor
probably costs ten times what it would in a release version. And the debug heap is
substantially slower than the release heap, because of internal consistency checks which
are done.
In debug mode, you worry about getting it right. But if you are trying to measure
performance, you can ONLY measure this meaningfully in an optimized release version. So if
you are worried about performance, you must measure performance in a release mode to get
meaningful data.
joe
On Tue, 28 Jun 2005 07:57:51 GMT, "EggNChips" <address@xxxxxxxxxx> wrote:
>Hi all,
>
>Looking for guidance / suggestions. My application uses a CPtrArray within
>the doc class to hold pointers to a bunch of structs. On DeleteContents()
>my app steps through the CPtrArray to delete each of the elements. The
>problem I am coming accross is poor performance, on my P4 1.6Ghz it is
>taking 7.5 seconds to step through 5000 records, this seems excessive to me
>and wondering if I would be better using a different class or method to
>reduce this time.
>
>BTW I have tried GetAt and ElemeatAt and they don't make any real
>difference.
>
>
>void CPartsDoc::DeleteContents()
>{
>
>int Records, Counter;
>SSmallPartItem * Item;
>
>
>
> Records=m_DataArray.GetSize();
>
>
>
> for(Counter=0;Counter<Records;Counter++)
> {
> Item=(SSmallPartItem *)m_DataArray[Counter];
> delete Item;
>
> }
>
>
> m_DataArray.RemoveAll();
>
>
> CDocument::DeleteContents();
>}
>
Joseph M. Newcomer [MVP]
email: newcomer@xxxxxxxxxxxx
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
.
- References:
- CPtrArray Performance
- From: EggNChips
- CPtrArray Performance
- Prev by Date: Re: Doing things on entry and exit to wizard pages?
- Next by Date: Re: GetUniqueFileName
- Previous by thread: Re: CPtrArray Performance
- Next by thread: Loading Icon From resource-failed - VC++ matlab Interface
- Index(es):
Relevant Pages
|