Sign in to follow this  
johnnyBravo

Are std::vectors slow compared to using pointers?

Recommended Posts

johnnyBravo    100
Hi, in my program i'm doing a fps count, and when I stick a vector inside a loop that goes 400 times I get like 15fps, but when I use a dynamic pointer array instead, i get about 180fps. btw i am also adding values into these arrays. And my loop only contains what I described above. From that it seems that vectors are quite slow. Has anyone else had this experience? As it seems to me dynamic pointer arrays are much faster. Or is this some weird problem and something is going wrong? thx

Share this post


Link to post
Share on other sites
Zahlman    1682
std::vector *copies* objects in when you insert them into the vector, which implies calling a copy constructor.

This isn't how you want to work with STL (i.e. adding things to a list in an inner loop / on every frame). It's probably not how you want to work *at all*.

Share this post


Link to post
Share on other sites
petewood    819
There shouldn't be any difference.

First: Make sure you're using release mode. In debug there is lots of extra info.

Second: Your rating is quite low so I wonder whether you're joking.

Third: If you are comparing std::vector with a dynamic pointer array, how are you doing the inserts by hand? I doubt you've coded something by hand which is doing the same thing as std::vector which is 12x faster.

Fourth: If you are inserting in the middle of the vector you should probably use a list instead.

Fifth: If you're adding stuff to the end of the vector you should probably use std::deque.

Sixth: Show us your code.

Share this post


Link to post
Share on other sites
johnnyBravo    100
I've also got speed loss using char [] over std::string.

My ratings low most probably as i use get involved on those political discussions in the lounge....

I don't know if its my code that is buggy or what, but its pretty straight forward, I've never really experienced such problems before.

What I'm doing is i'm looping through a 2D array(200 x 200).
I'm checking if the value of each cell equals 2 or 3, and if they do equal that i add them to the vector.

I really can't understand why it is going so slow.

heres the code:

globals...
vector<vector<int> > cell;
and it is so far all equal 0, ive initialised it somewhere else.

Point is a class that just holds x,y integers.

for(int x=0;x<(int)cell.size();x++) {
for(int y=0;y<(int)cell[x].size();y++) {
std::vector<Point> neighbours;

for(int i=0;i<8;i++) {
Point p(x,y);
neighbours.push_back(p);
}
}
}




All this code is run inside the win32 message loop thing.

Right now, it freezes(running super slow) with the neighbours.push_back(p); inside that for loop 0 to 8.

And if i take it out of that for i loop, it runs reallly slowly.

Any insight?
Thanks

Share this post


Link to post
Share on other sites
snk_kid    1312
Quote:
Original post by johnnyBravo

for(int x=0;x<(int)cell.size();x++) {
for(int y=0;y<(int)cell[x].size();y++) {
std::vector<Point> neighbours;

for(int i=0;i<8;i++) {
Point p(x,y);
neighbours.push_back(p);
}
}
}



Well thats not suprising, that is some strange code,

firstly you obtaining the size repeatedly for no reason, cells's size doesn't change then just get the size once e.g.


typedef std::vector< std::vector<int> > foo_vec;

for(foo_vec::size_type x = 0, m = cells.size();
x < m;
++x) {

for(foo_vec::size_type y = 0, n = cells[x].size();
y < n;
++y)


every time the second inner loop has ended "neighbours" is destroyed by scope so what good as is that?

Then what i also have question is that for all the 8 elements of "neighbours" you make a copy of the same Point so you don't need to write another loop e.g.

std::vector<Point> neighbours(8, Point(x, y));

another thing is you should look into is std::vector::reserve look it up here

Share this post


Link to post
Share on other sites
petewood    819

for(int x=0;x<(int)cell.size();x++) {
for(int y=0;y<(int)cell[x].size();y++) {
std::vector<Point> neighbours;
for(int i=0;i<8;i++) {
//the size of neighbours always needs to be 8
Point p(x,y);
//if neighbours isn't big enough push_back will
//create a new internal array and copy everything
neighbours.push_back(p);
}
//you don't do anything with neighbours so it gets deleted
//I guess you're using it really but this doesn't seem efficient
}
}

Share this post


Link to post
Share on other sites
VincentLascaux    112
Use reserve


for(int x=0;x<(int)cell.size();x++) {
for(int y=0;y<(int)cell[x].size();y++) {
std::vector<Point> neighbours;
neighbours.reserve(8);

for(int i=0;i<8;i++) {
Point p(x,y);
neighbours.push_back(p);
}
}
}


Can you show the code that you claim faster using dynamic pointers?

Share this post


Link to post
Share on other sites
snk_kid    1312
Quote:
Original post by VincentLascaux
Use reserve


for(int x=0;x<(int)cell.size();x++) {
for(int y=0;y<(int)cell[x].size();y++) {
std::vector<Point> neighbours;
neighbours.reserve(8);

for(int i=0;i<8;i++) {
Point p(x,y);
neighbours.push_back(p);
}
}
}


Can you show the code that you claim faster using dynamic pointers?


No you don't have to use reserve & third explicit loop in this case e.g.


typedef std::vector< std::vector<int> > foo_vec;

for(foo_vec::size_type x = 0, m = cells.size();
x < m;
++x)
for(foo_vec::size_type y = 0, n = cells[x].size();
y < n;
++y)
std::vector<Point> neighbours(8, Point(x, y));


But again i question what use "neighbours" has when the second inner loop is finished "neighbours" is destroyed by scope.

Share this post


Link to post
Share on other sites
petewood    819
This should be far more efficient.

int xsize = cell.size()
for(int x=0;x<xsize;x++) {
int ysize = cell[x].size();
for(int y=0;y<ysize;y++) {
//create right size and with default value
std::vector<Point> neighbours(8, Point(x, y));
}
}


However, I am inclined to think you haven't shown us the real code. neighbours gets destroyed so the whole loop is a waste of time. It would be quicker to do:


//

Share this post


Link to post
Share on other sites
fiskbil    252
Creating a new vector for each loop will give you a small vector that will have to reallocate memory a lot of times during the loop. Instead, put the declaration of the vector outside all loops and put neighbours.resize(0) where you have the declaration now.

resize makes sure the memory is still allocated, but you can still push_back and it replaces the next available element. So basically the vector won't have to reallocate memory all the time and you can use push_back() just as the way you want to.

Share this post


Link to post
Share on other sites
johnnyBravo    100
Ok, heres the code i think is faster using a dynamic buffer.

btw I am using the neighbours etc, I am just not portraying it here, as the speed is being serverely comprised without it anyway.

So basically the "neighbours" list won't always be 8 elements, it could be 0, 1 or 2 etc.


.................
ok i just rewrote that dynamic pointer code "properly" and you guys are right! I get the same speed.

I just thought c++ could handle code called in such a way :)

anyway im looking into reserve now, thanks


edit:

just a quick question, which is a tiny bit related.

Is it slower to say do this:

//note this is only a bad example
for(int i=0;i<111;i++) {
//slower to do this
int num = i*5;

if(num ==20)
}

//instead of this
if(i*5==20) //that is if i am only using i*5 once
}


Share this post


Link to post
Share on other sites
petewood    819
Quote:
Original post by snk_kid
petewood: You said basically the exact same thing as i have [lol]


Yeah, you beat me to it.

Hey, this isn't a competition, at least not any more. We used to be neck and neck. We were both 1337.

Share this post


Link to post
Share on other sites
VincentLascaux    112
Quote:
Original post by snk_kid
No you don't have to use reserve & third explicit loop in this case e.g.


typedef std::vector< std::vector<int> > foo_vec;

for(foo_vec::size_type x = 0, m = cells.size();
x < m;
++x)
for(foo_vec::size_type y = 0, n = cells[x].size();
y < n;
++y)
std::vector<Point> neighbours(8, Point(x, y));


But again i question what use "neighbours" has when the second inner loop is finished "neighbours" is destroyed by scope.


Come on ! It's obvious that it's not real code ! He won't put 8 times the same point in a vector (I assume... :))
In a general true situation, you would put different points in the neighbours vector and wouldn't be able to use this constructor.

But you are right that giving us such small and unrealistic code doesnt help. The compiler could just see that the loop is doing nothing and not put it in the exe.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this