Re: Zero-size array as struct member
Goran Pusic <goranp@cse-semaphore.com> wrote:
On Aug 20, 12:34?pm, Juha Nieminen <nos...@thanks.invalid> wrote:
?? Tiib <oot...@hot.ee> wrote:
In C++ you should use vector<int> instead, it is about as fast.
? In which system, exactly?
? Unfortunately 'new' (and 'delete') is a rather heavy operation with
most C/C++ standard memory allocators, and if you use std::vector in
the place of the struct hack, you will be doing two 'news' instead of
one malloc().
Why? IMO, new and delete are, on the success path, practically
equivalent on many common implementations. Difference is one if on
malloc failure, and new is inlined.
You are basing your claims on your personal *opinion*? Rather than,
you know, actually testing it in practice?
I say this claim of yours is poorly founded.
It's quite well founded. For example, take this short piece of code:
int main()
{
std::set<int> someSet;
for(int i = 0; i < 10000000; ++i) someSet.insert(i);
}
Compiling that with "g++ -O3 -march=native" on my Pentium4 system takes
about 10 seconds. So, where do you think all that time is spent? Perhaps
rearranging the binary tree each time a new element is inserted? That sounds
like something which would take its time.
Nope. The majority of that time is spent *allocating memory*. If I
change the above code to use a very fast memory allocator, such as
http://warp.povusers.org/FSBAllocator/ so that the declaration of 'someSet'
becomes:
std::set<int, std::less<int>, FSBAllocator<int> > someSet;
then the running time drops down to about 2.5 seconds.
From the 10 seconds running time of the original program above over
7.5 seconds is spent solely on memory allocation and deallocation.
That's quite a *lot*. (There are many reasons why this is so, one of the
major ones being that the default allocator is thread-safe, which the
FSBAllocator above isn't.)
'new' and 'delete' are significantly heavy operations.
? Additionally, using std::vector there will increase memory fragmentation,
making things even worse.
In this case, you can use vector::reserve, so not really.
If you are allocating a million instances of the struct, each such
instance having an std::vector object inside, reserve() would do nothing
to alleviate the memory fragmentation.
And even locality of reference is not a concern, because allocators
mostly do a good job of allocating blocks close in space if allocation
is close in time. E.g.
std::vector* p = new vector;
p->reserve(X);
is in practice quite OK wrt locality.
Not if the memory is heavily fragmented, which is one major problem here.