473,763 Members | 1,893 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

efficiency of vector of pointers.

smp
Does anyone know why making a vector of pointers is so much less efficient
than a vector of objects? For a simple example:

int num = 20;
vector<int*v_in t_ptr;
v_int_ptr.reser ve(num);

for(int i = 0; i < num; i++)
{
int* my_int_ptr = new int;
*my_int_ptr = i;
v_int_ptr.push_ back(my_int_ptr );
}

takes a long time and uses up pretty much all the memory when num is
large. However, the functionally equivalent:

int num = 20;
vector<intv;
v.reserve(num);
for(int i = 0; i < num; i++)
{
double my_int = i;
v.push_back(myi nt);
}

runs very fast under the same conditions that bogged down the former. And
by the way, I'm trying to avoid using arrays.
Finally, what is the best way to deallocate the memory here? Does one need
to iterate through the vector deleting each block in turn?

Thanks in advance,
SMP
Oct 19 '07 #1
13 2890
On Oct 19, 7:26 pm, smp <spear...@stude nt.ucr.eduwrote :
Does anyone know why making a vector of pointers is so much less efficient
than a vector of objects? For a simple example:

int num = 20;
vector<int*v_in t_ptr;
v_int_ptr.reser ve(num);

for(int i = 0; i < num; i++)
{
int* my_int_ptr = new int;
*my_int_ptr = i;
v_int_ptr.push_ back(my_int_ptr );
}

takes a long time and uses up pretty much all the memory when num is
large. However, the functionally equivalent:

int num = 20;
vector<intv;
v.reserve(num);
for(int i = 0; i < num; i++)
{
double my_int = i;
v.push_back(myi nt);
}

runs very fast under the same conditions that bogged down the former. And
by the way, I'm trying to avoid using arrays.
Finally, what is the best way to deallocate the memory here? Does one need
to iterate through the vector deleting each block in turn?

Thanks in advance,
SMP
new() and delete() functions take a lot of real time. Depending on
your compiler, pointer sizes may be big, hence, a memory hog too. To
deallocate, use v.clear().

Oct 19 '07 #2
smp wrote:
Does anyone know why making a vector of pointers is so much less
efficient than a vector of objects? For a simple example:

int num = 20;
vector<int*v_in t_ptr;
v_int_ptr.reser ve(num);

for(int i = 0; i < num; i++)
{
int* my_int_ptr = new int;
*my_int_ptr = i;
v_int_ptr.push_ back(my_int_ptr );
}

takes a long time and uses up pretty much all the memory when num is
large. However, the functionally equivalent:

int num = 20;
vector<intv;
v.reserve(num);
for(int i = 0; i < num; i++)
{
double my_int = i;
v.push_back(myi nt);
}

runs very fast under the same conditions that bogged down the former.
And by the way, I'm trying to avoid using arrays.
Well what do you expect? The first example calls new each time round
the loop. It's not what goes in the vector, its how that object is
created. Now consider the case where the object stored in the vector is
expensive to copy and compare that with a vector of pointers to said
objects.
Finally, what is the best way to deallocate the memory here? Does one
need to iterate through the vector deleting each block in turn?
In the first case, yes, the every new requires a delete rule applies.
This is one reason smart pointer types are often stored in standard
containers.

--
Ian Collins.
Oct 20 '07 #3
Zilla wrote:
On Oct 19, 7:26 pm, smp <spear...@stude nt.ucr.eduwrote :
>Does anyone know why making a vector of pointers is so much less
efficient than a vector of objects? For a simple example:

int num = 20;
vector<int*v_in t_ptr;
v_int_ptr.reser ve(num);

for(int i = 0; i < num; i++)
{
int* my_int_ptr = new int;
*my_int_ptr = i;
v_int_ptr.push_ back(my_int_ptr );
}

takes a long time and uses up pretty much all the memory when num is
large. However, the functionally equivalent:

int num = 20;
vector<intv;
v.reserve(num);
for(int i = 0; i < num; i++)
{
double my_int = i;
v.push_back(myi nt);
}

runs very fast under the same conditions that bogged down the former. And
by the way, I'm trying to avoid using arrays.
Finally, what is the best way to deallocate the memory here? Does one
need to iterate through the vector deleting each block in turn?

Thanks in advance,
SMP

new() and delete() functions take a lot of real time. Depending on
your compiler, pointer sizes may be big, hence, a memory hog too. To
deallocate, use v.clear().
v.clear() will _not_ deallocate the elements of the vector. It will just
call the trivial destructor for each int* stored. Consequently, a call to
v.clear() without going through v and calling delete on all the pointers
will leak memory big time.

Moreover, v.clear() is not guaranteed to deallocate any memory allocated by
the vector v. In particular, v.capacity() may or may not change.
Best

Kai-Uwe Bux
Oct 20 '07 #4
er
On Oct 19, 10:34 pm, Kai-Uwe Bux <jkherci...@gmx .netwrote:
Zilla wrote:
On Oct 19, 7:26 pm, smp <spear...@stude nt.ucr.eduwrote :
Does anyone know why making a vector of pointers is so much less
efficient than a vector of objects? For a simple example:
int num = 20;
vector<int*v_in t_ptr;
v_int_ptr.reser ve(num);
for(int i = 0; i < num; i++)
{
int* my_int_ptr = new int;
*my_int_ptr = i;
v_int_ptr.push_ back(my_int_ptr );
}
takes a long time and uses up pretty much all the memory when num is
large. However, the functionally equivalent:
int num = 20;
vector<intv;
v.reserve(num);
for(int i = 0; i < num; i++)
{
double my_int = i;
v.push_back(myi nt);
}
runs very fast under the same conditions that bogged down the former. And
by the way, I'm trying to avoid using arrays.
Finally, what is the best way to deallocate the memory here? Does one
need to iterate through the vector deleting each block in turn?
Thanks in advance,
SMP
new() and delete() functions take a lot of real time. Depending on
your compiler, pointer sizes may be big, hence, a memory hog too. To
deallocate, use v.clear().

v.clear() will _not_ deallocate the elements of the vector. It will just
call the trivial destructor for each int* stored. Consequently, a call to
v.clear() without going through v and calling delete on all the pointers
will leak memory big time.

Moreover, v.clear() is not guaranteed to deallocate any memory allocated by
the vector v. In particular, v.capacity() may or may not change.

Best

Kai-Uwe Bux
if your vector grows sequentially, reallocation will occur. in this
case, ptrs might be preferable if each element is big (unlike your
example), unless, of course, you know in advance how many elements
will be inserted (reserve).

this point was made earlier:
http://groups.google.com/group/comp....9d782f6d6dae52

Oct 20 '07 #5
On Oct 20, 1:44 am, Zilla <zill...@bellso uth.netwrote:
On Oct 19, 7:26 pm, smp <spear...@stude nt.ucr.eduwrote :
Does anyone know why making a vector of pointers is so much less efficient
than a vector of objects? For a simple example:
int num = 20;
vector<int*v_in t_ptr;
v_int_ptr.reser ve(num);
for(int i = 0; i < num; i++)
{
int* my_int_ptr = new int;
*my_int_ptr = i;
v_int_ptr.push_ back(my_int_ptr );
}
takes a long time and uses up pretty much all the memory when num is
large. However, the functionally equivalent:
int num = 20;
vector<intv;
v.reserve(num);
for(int i = 0; i < num; i++)
{
double my_int = i;
v.push_back(myi nt);
}
runs very fast under the same conditions that bogged down the former. And
by the way, I'm trying to avoid using arrays.
Finally, what is the best way to deallocate the memory here? Does one need
to iterate through the vector deleting each block in turn?
new() and delete() functions take a lot of real time. Depending on
your compiler, pointer sizes may be big, hence, a memory hog too.
In one case, each element uses sizeof(int) memory, period. In
the other, each element in the vector is sizeof(int*), but
there's also the int which is pointed to, plus the additional
overhead associated with dynamic allocation (at least 8 bytes on
most machines, often more). So in a best case analysis, where
both pointers and int's are four bytes, vector<int*will use 4
times more memory than vector<int>.
To
deallocate, use v.clear().
That won't deallocate anything.

--
James Kanze (GABI Software) email:ja******* **@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientier ter Datenverarbeitu ng
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Oct 20 '07 #6
On Oct 20, 4:34 am, Kai-Uwe Bux <jkherci...@gmx .netwrote:

[...]
v.clear() will _not_ deallocate the elements of the vector. It will just
call the trivial destructor for each int* stored. Consequently, a call to
v.clear() without going through v and calling delete on all the pointers
will leak memory big time.
Moreover, v.clear() is not guaranteed to deallocate any memory allocated by
the vector v. In particular, v.capacity() may or may not change.
v.clear() is guaranteed by the standard to not reduce the
capacity(), and so in practice will never deallocate memory
allocated by the vector itself.

--
James Kanze (GABI Software) email:ja******* **@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientier ter Datenverarbeitu ng
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Oct 20 '07 #7
James Kanze wrote:
On Oct 20, 4:34 am, Kai-Uwe Bux <jkherci...@gmx .netwrote:

[...]
>v.clear() will _not_ deallocate the elements of the vector. It will just
call the trivial destructor for each int* stored. Consequently, a call to
v.clear() without going through v and calling delete on all the pointers
will leak memory big time.
>Moreover, v.clear() is not guaranteed to deallocate any memory allocated
by the vector v. In particular, v.capacity() may or may not change.

v.clear() is guaranteed by the standard to not reduce the
capacity(), and so in practice will never deallocate memory
allocated by the vector itself.
Where would I find that in the standard? I only found that the semantics of
clear() is defined as erase( begin(), end() ). Regarding erase(), I did not
find any statement in the standard as to how it may or may not affect the
capacity. The closest provision I found is that erase does not invalidate
iterators before the erased range and hence it will generally not cause
reallocation (however, that is vacuous when all elements are erased). Or is
it just by absence: it is not mentioned in the Effects clause that the
capacity could change, therefore it cannot change?
Best

Kai-Uwe Bux
Oct 20 '07 #8
smp <sp******@stude nt.ucr.eduwrote :
Does anyone know why making a vector of pointers is so much less efficient
than a vector of objects? For a simple example:

int num = 20;
vector<int*v_in t_ptr;
v_int_ptr.reser ve(num);

for(int i = 0; i < num; i++)
{
int* my_int_ptr = new int;
*my_int_ptr = i;
v_int_ptr.push_ back(my_int_ptr );
}

takes a long time and uses up pretty much all the memory when num is
large. However, the functionally equivalent:

int num = 20;
vector<intv;
v.reserve(num);
for(int i = 0; i < num; i++)
{
double my_int = i;
v.push_back(myi nt);
}

runs very fast under the same conditions that bogged down the former. And
by the way, I'm trying to avoid using arrays.
Finally, what is the best way to deallocate the memory here? Does one need
to iterate through the vector deleting each block in turn?
We can see that the first code sample allocates a block of memory that
is sizeof( int* ) * 20 then allocates 20 blocks that are each sizeof(
int ), while the second code sample only allocates a single sizeof( int
) * 20 block. If sizeof( int* ) == sizeof( int ) [not necessarily true]
then one can see that the first sample allocates at least twice as much
total ram as the second, and 20 more blocks than the second. These two
facts alone account for all of the speed and memory difference.
Oct 20 '07 #9
On Oct 19, 7:26 pm, smp <spear...@stude nt.ucr.eduwrote :
Does anyone know why making a vector of pointers is so much less efficient
than a vector of objects? For a simple example:

int num = 20;
vector<int*v_in t_ptr;
v_int_ptr.reser ve(num);

for(int i = 0; i < num; i++)
{
int* my_int_ptr = new int;
*my_int_ptr = i;
v_int_ptr.push_ back(my_int_ptr );
}

takes a long time and uses up pretty much all the memory when num is
large. However, the functionally equivalent:

int num = 20;
vector<intv;
v.reserve(num);
for(int i = 0; i < num; i++)
{
double my_int = i;
v.push_back(myi nt);
}

runs very fast under the same conditions that bogged down the former. And
by the way, I'm trying to avoid using arrays.
Finally, what is the best way to deallocate the memory here? Does one need
to iterate through the vector deleting each block in turn?

Thanks in advance,
SMP
new and delete for very small objects is typically inefficient, vector
or not. Assuming that your new/delete is pointing to a general purpose
heap allocator underneath the hood (typically malloc ) why is this?
1. each call to new requires scanning free blocks looking for enough
space. This is typically and O(log n) search (where 'n' is the number
of free blocks)
2. In addition to the sizeof(int) memory required, you allocator is
going to add its own bookkeeping, usually sizeof(a few pointers). Plus
the minimum size chunk it is going to make is typically 16 bytes.
Since int only needs four, you've just claimed about 20 bytes extra
3. On an MT system, new/delete is going to cost you a mutex lock
4. delete is typically an O(n) operation (n being the number of times
you called new). If you ran your program through a very good profiler,
you would consistently find that "delete" operation take up way more
time than "new" (This is one reason that people find throwing an
exception very costly - as it is unwinding the stack, it is calling a
bunch of destructors, and dtor is where you find a lot of "deletes" )
5. There is no guarantee that the memory returned by successive calls
to "new" is placed anywhere near each other in memory. So your
processors cache keeps getting flushed and reloaded. Also, recall
that a typical L1 cache line is 16 bytes. Well, we just observed that
memory returned by new is going to take up about 20 odd bytes minimum.
So each 4 byte int needs an entire cache line. Ouch
6. the memory returned by new has maximum alignment, no matter what
type you are actually newing. No optimization can be performed based
on the fact that int does not always need maximum alignment.

OK so what does vector do? It just keeps one big contiguous chunk of
ints. So all of the observations above are amortized over many many
ints (in your example everything is done in reserve() and dtor), and
your cache likes it because all these ints are perfectly aligned and
jammed right next to each other.
You may also want to consider using deque if you are doing a lot of
insertions like your example. See http://www.codeproject.com/vcpp/stl/vector_vs_deque.asp

The moral of the story: only use container of pointers when
a) you need the object shared by other containers or some other object
b) the object is expensive to copy (large or complicated objects), or
is not copyable at all
c) you are making a container of abstract classes (you have no other
choice but use a pointer
Excessive calls to new is often a problem seen in C++ programs written
by Java developers. The Java allocator is completely different, and
the language itself accounts for this difference (one reason there are
no dtors in Java). Typically in Java, calls to new are constant time
(not including time to call objects ctor) and deallocation is behind
the scenes, outside of normal program flow. Of course, Java systems
developers are always struggling with Java's deallocation problems,
but that is a different story.

For delete, the easiest way is to use a shared_ptr . But if you have
performance worries now, using shared_ptr for a vector of int* is even
worse. This is how I do it
template<class T>struct deleteme{
void operator()(T t){delete t;}
};
std::for_each(m ycontainer.begi n(),mycontainer .end(),deleteme <int*>());

Lance

Oct 20 '07 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

9
2974
by: luigi | last post by:
Hi, I am trying to speed up the perfomance of stl vector by allocating/deallocating blocks of memory manually. one version of the code crashes when I try to free the memory. The other version seem to work. I would appreciate someone to comment on this. Version 1 (crashes on deallocating) #include <iostream>
10
3053
by: Jason | last post by:
Hi, I have a few million data items being received by my program and I wish to store them in a list, with each item being inserted in any position in the list. Any performance tips so that my program runs ok? I have checked out the STL and have thought of using vector, set, list, deque and map. I dont know how these things are implemented so not sure which is best to use or if i should implement another data structure. Perhaps any...
14
5027
by: Jim West | last post by:
I'm curious why I might be getting such a large performance difference between using a map iterator and a vector iterator. This is a computational electromagnetics code where I have to separate points in space that arrive randomly into groupings based on (x, y, z) dimensions, so I use std::map to do that. Once the sorting is done I need to find the interactions between groups, so I've been using iterators to step through the map. As a...
17
4171
by: Mark P | last post by:
Say I have objects of class C which are fairly large. Then consider: vector<C> vc; vc.push_back(C()); Naively this would seem to construct a temporary object C(), copy it into the space owned by the vector, and then delete the temporary object. I realize this is implementation dependent, but will most modern compilers optimize away the creation of the temporary object, or is
9
2308
by: kathy | last post by:
I am using std::vector in my program: func() { std::vector <CMyClass *> vpMyClass; vpMyClass.push_back(new CMyClass()); vpMyClass.push_back(new CMyClass()); vpMyClass.push_back(new CMyClass()); //???? Required ??????????????//
4
2473
by: Mark P | last post by:
Consider the following: // Contrast different ways of inserting into a map #include <map> #include <iostream> using namespace std; struct A
83
3675
by: Licheng Fang | last post by:
Hi, I'm learning STL and I wrote some simple code to compare the efficiency of python and STL. //C++ #include <iostream> #include <string> #include <vector> #include <set> #include <algorithm> using namespace std;
4
3512
by: Josefo | last post by:
Hello, is someone so kind to tell me why I am getting the following errors ? vector_static_function.c:20: error: expected constructor, destructor, or type conversion before '.' token vector_static_function.c:21: error: expected constructor, destructor, or type conversion before '.' token
43
4834
by: john | last post by:
Hi, in TC++PL 3 on pages 674-675 it is mentioned: "Maybe your first idea for a two-dimensional vector was something like this: class Matrix { valarray< valarray<doublev; public: // ... };
0
9566
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9389
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10149
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
10003
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
9943
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
6643
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5410
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
2
3529
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
2797
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.