473,395 Members | 1,496 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,395 software developers and data experts.

returning a vector


Which method is the fastest/best:

std::vector<intfoo1()
{
std::vector<intv;
...
reutun v;
}

std::vector<int>& foo2()
{
static std::vector<intv;
...
reutun v;
}

void foo3(std::vector<int>&v)
{
...
}

I tend to say foo3 is the best, however foo1 and foo2 are more
"convenient". Is there any way of returning a vector as fast as with
foo3?
--
-Gernot
int main(int argc, char** argv) {printf
("%silto%c%cf%cgl%ssic%ccom%c", "ma", 58, 'g', 64, "ba", 46, 10);}

Sep 21 '06 #1
13 2278
On 2006-09-21, Gernot Frisch <Me@Privacy.netwrote:
Which method is the fastest/best:

std::vector<intfoo1()
{
std::vector<intv;
...
reutun v;
}

std::vector<int>& foo2()
{
static std::vector<intv;
...
reutun v;
}
Not thread safe, i strongly recommend against this one (regardless of
speed).

void foo3(std::vector<int>&v)
{
...
}

I tend to say foo3 is the best, however foo1 and foo2 are more
"convenient". Is there any way of returning a vector as fast as with
foo3?
You could measure it for yourself, though i doubt that you will see
significant differences (you may get better performance by not using
std::vector, at the cost of convenience).

--
Roland Csaszar ----------- \\\ /// -------------- +43 316 495 2129
Software Development ------ \\\ /// ----------- http://www.knapp.com
KNAPP Logistics Automation - \\V// - mailto:ro************@knapp.com
Sep 21 '06 #2
Gernot Frisch napisał(a):
Which method is the fastest/best:

std::vector<intfoo1()
{
std::vector<intv;
...
reutun v;
}
May be fast as foo3 if the compiler has RVO.
>
std::vector<int>& foo2()
{
static std::vector<intv;
...
reutun v;
}
badly programmed.
>
void foo3(std::vector<int>&v)
{
...
}
preferred.
--
Marcin Gabryszewski
G DATA Software
www.gdata.pl

address:<FirstName><dot><Surname><at><gdata><dot>< pl>
Sep 21 '06 #3

Gernot Frisch wrote:
Which method is the fastest/best:

std::vector<intfoo1()
{
std::vector<intv;
...
reutun v;
}
With a good compiler, the method shown above will be fastest if the
function is used in initialisation:
std::vector<inttest = foo1();

If you use it to reassign, it gets less efficient (but a proposal to
extend the language will bring back efficiency):

std::vector<inttest;
....
test = foo1();
You can regain speed by using std::swap.
>
std::vector<int>& foo2()
{
static std::vector<intv;
...
reutun v;
}
This is not fast at all: The callee will have to copy the entire
vector.
>
void foo3(std::vector<int>&v)
{
...
}
This one will be pretty fast to. The problem is in ease of use and
intent: Initialisation is no longer possible:
std::vector<inttest;
test = foo3();

Also, the code will no longer have the strong exception guarantee (as
presumably foo3 begins by clearing the vector).

I would choose foo1 as the default implementation, and perhaps supply
foo3 as:

void foo3(std::vector<int>&v) { std::vector<inttemp = foo1();
std::swap(v,temp); }.
>
I tend to say foo3 is the best, however foo1 and foo2 are more
"convenient". Is there any way of returning a vector as fast as with
foo3?
/Peter

Sep 21 '06 #4

Gernot Frisch wrote:
Which method is the fastest/best:
I tend to say foo3 is the best, however foo1 and foo2 are more
"convenient". Is there any way of returning a vector as fast as with
foo3?
How about (4):

typedef std::vector<intivect;
std::auto_ptr<ivectfoo()
{
...
}

IMO this is more flexible than the other options. Your option (3) does
not cater for reserving the size for usage in foo... Also, using (4),
the caller can decide whether or not he wants to keep the result. Using
(3) with a swap causes de-allocation of the argument. (4) provides you
with flexibility. The only other concern that you may have is heap
usage, but then you would not be using a vector. (2) is not thread
safe, as previously mentioned - other than that it seems a good option
(if thread safety not required). I don't think (3) is that good,
especially considering the possibility of re-allocation in foo.

Kind regards,

Werner

Sep 21 '06 #5
peter koch <pe***************@gmail.comwrote:
Gernot Frisch wrote:
>std::vector<int>& foo2()
{
static std::vector<intv;
...
reutun v;
}

This is not fast at all: The callee will have to copy the entire
vector.
He is returning a reference to the vector and not the vector itself, so
I think it should be pretty fast.

--
Marcus Kwok
Replace 'invalid' with 'net' to reply
Sep 21 '06 #6

Marcus Kwok wrote:
peter koch <pe***************@gmail.comwrote:
Gernot Frisch wrote:
std::vector<int>& foo2()
{
static std::vector<intv;
...
reutun v;
}
This is not fast at all: The callee will have to copy the entire
vector.

He is returning a reference to the vector and not the vector itself, so
I think it should be pretty fast.
Yes, but unless you are using a reference variable:

vector<int& x = foo2();

you are doing a copy or initialization same as #1 without possibility
for optimization. This could be efficient given very specific
conditions but in general will not be.

Sep 21 '06 #7
Noah Roberts <ro**********@gmail.comwrote:
Marcus Kwok wrote:
>peter koch <pe***************@gmail.comwrote:
Gernot Frisch wrote:
std::vector<int>& foo2()
{
static std::vector<intv;
...
reutun v;
}

This is not fast at all: The callee will have to copy the entire
vector.

He is returning a reference to the vector and not the vector itself, so
I think it should be pretty fast.

Yes, but unless you are using a reference variable:

vector<int& x = foo2();

you are doing a copy or initialization same as #1 without possibility
for optimization. This could be efficient given very specific
conditions but in general will not be.
Thanks, I see your point and thinking over it, of course you're right.
If foo2() were to be used in some sort of function chaining then it
might be beneficial, but in the context of the OP (returning the vector
to be stored somewhere) a copy will probably be made.

My apologies to peter koch for calling him out when I was wrong.

--
Marcus Kwok
Replace 'invalid' with 'net' to reply
Sep 21 '06 #8

Marcus Kwok wrote:
peter koch <pe***************@gmail.comwrote:
Gernot Frisch wrote:
std::vector<int>& foo2()
{
static std::vector<intv;
...
reutun v;
}
This is not fast at all: The callee will have to copy the entire
vector.

He is returning a reference to the vector and not the vector itself, so
I think it should be pretty fast.
Right. As Noah mentioned, this would be okay if the user initialised
the variable with a reference as in:

std::vector<int>& vec1 = foo2();

But this is dangerous if e.g. the user calls foo2 while there still are
references to the static vector. Now one will change behind your back!
This is the same problem as in a multithreaded environment except that
here you can have the problem without even using threads!

/Peter

Sep 21 '06 #9
Roland.Csaszar wrote:
On 2006-09-21, Gernot Frisch <Me@Privacy.netwrote:
Which method is the fastest/best:

std::vector<intfoo1()
{
std::vector<intv;
...
reutun v;
}

std::vector<int>& foo2()
{
static std::vector<intv;
...
reutun v;
}

Not thread safe, i strongly recommend against this one (regardless of
speed).
Right.
>
void foo3(std::vector<int>&v)
{
...
}

I tend to say foo3 is the best, however foo1 and foo2 are more
"convenient". Is there any way of returning a vector as fast as with
foo3?

You could measure it for yourself, though i doubt that you will see
significant differences (you may get better performance by not using
std::vector, at the cost of convenience).
Huh? Try returning a very large vector or one that is expensive to
copy. Absent the return value optimization and/or the proper client
code to make use of it, foo3 is certainly faster than foo1.

Cheers! --M

Sep 21 '06 #10
peter koch wrote:
Gernot Frisch wrote:
Which method is the fastest/best:

std::vector<intfoo1()
{
std::vector<intv;
...
reutun v;
}

With a good compiler, the method shown above will be fastest if the
function is used in initialisation:
std::vector<inttest = foo1();

If you use it to reassign, it gets less efficient (but a proposal to
extend the language will bring back efficiency):

std::vector<inttest;
...
test = foo1();
You can regain speed by using std::swap.

std::vector<int>& foo2()
{
static std::vector<intv;
...
reutun v;
}

This is not fast at all: The callee will have to copy the entire
vector.

void foo3(std::vector<int>&v)
{
...
}

This one will be pretty fast to. The problem is in ease of use and
intent: Initialisation is no longer possible:
std::vector<inttest;
test = foo3();

Also, the code will no longer have the strong exception guarantee (as
presumably foo3 begins by clearing the vector).

I would choose foo1 as the default implementation, and perhaps supply
foo3 as:

void foo3(std::vector<int>&v) { std::vector<inttemp = foo1();
std::swap(v,temp); }.
Good advice. Here's a quote from from _Efficient C++ Programming_ by
Lippman (http://tinyurl.com/eznwx) that talks about the same things:

----
Matrix mat;
while ( something.more() )
{
mat = something.fetch_mat();
// do something with mat ...

}

mat is set to a different Matrix class object with each iteration. The
programmer could have written

while ( something.more() )
{
Matrix mat = something.fetch_mat();
// do something with mat ...

}

but wished to avoid the construction and destruction of mat with each
loop iteration. Let's rather initialize and destroy it once prior to
and after completion of the loop, the programmer explains, not
realizing that with each iteration, the assignment requires that a
temporary be passed to fetch_mat(), where it is constructed. The
temporary is then copy assigned to mat and destructed. While placing
the definition of mat outside the loop appears more efficient, it is
actually more expensive, resulting in an additional copy assignment
operation with each loop iteration, in addition to the construction and
destruction of a temporary Matrix object.
---

Cheers! --M

Sep 21 '06 #11

peter koch wrote:
Gernot Frisch wrote:
Which method is the fastest/best:

std::vector<intfoo1()
{
std::vector<intv;
...
reutun v;
}

With a good compiler, the method shown above will be fastest if the
function is used in initialisation:
std::vector<inttest = foo1();
I thought the RVO needed a construct like so:

obj fun()
{
return obj();
}

Sep 21 '06 #12
Noah Roberts wrote:
peter koch wrote:
Gernot Frisch wrote:
Which method is the fastest/best:
>
std::vector<intfoo1()
{
std::vector<intv;
...
reutun v;
}
With a good compiler, the method shown above will be fastest if the
function is used in initialisation:
std::vector<inttest = foo1();

I thought the RVO needed a construct like so:

obj fun()
{
return obj();
}
Nope. See the Lippman excerpt I link to above.

Cheers! --M

Sep 21 '06 #13

mlimber wrote:
peter koch wrote:
[snip]
Matrix mat;
while ( something.more() )
{
mat = something.fetch_mat();
// do something with mat ...

}

mat is set to a different Matrix class object with each iteration. The
programmer could have written

while ( something.more() )
{
Matrix mat = something.fetch_mat();
// do something with mat ...

}

but wished to avoid the construction and destruction of mat with each
loop iteration. Let's rather initialize and destroy it once prior to
and after completion of the loop, the programmer explains, not
realizing that with each iteration, the assignment requires that a
temporary be passed to fetch_mat(), where it is constructed. The
temporary is then copy assigned to mat and destructed. While placing
the definition of mat outside the loop appears more efficient, it is
actually more expensive, resulting in an additional copy assignment
operation with each loop iteration, in addition to the construction and
destruction of a temporary Matrix object.
Right! It is always a pleasure when you program with the aim of having
the most readable program that you wind up also having the most
efficient. I can't count how many programs I've seen where an
obfuscation created to improve performance has the opposite effect.

/Peter

Sep 22 '06 #14

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

Similar topics

2
by: tornado | last post by:
hi all, i am pretty new to c++. i have this problem for which i am unable to think a solution. i don't understand how to pass a vector refernce back to the callin function. And how this...
9
by: mjm | last post by:
Folks, Stroustrup indicates that returning by value can be faster than returning by reference but gives no details as to the size of the returned object up to which this holds. My question is...
18
by: cppaddict | last post by:
Hi, Is it considered bad form to have the subscript operator return a const reference variable? If not, what is the proper way to do it? My question was prompted by the code below, my...
6
by: Affan Syed | last post by:
Hi, first let me apologize before hand for not knowing this trivial issue and my inability to find it after searching on the web for an answer to what seems to be starightforward. I have used...
8
by: Derek | last post by:
Some authors advocate returning const objects: const Point operator+(const Point&, const Point&); ^^^^^ Returning a const object prevents some bad code from compiling: Point a, b, c; (a +...
8
by: Richard | last post by:
what is the syntax for returning a vector? temp is a vector return temp; ? return temp<>; ? return temp<int>; ?
3
by: Michele | last post by:
Hello: What is the syntax for returning a reference to a vector from a function? I have a private vector and I want to return it using a public get function (like in the code below), but I...
7
by: arnuld | last post by:
/* C++ Primer - 4/e * * 1st example from section 7.2.2, page 234 * returning 2 values from a function * * STATEMENT: * to find a specific value in a vector and number of times * that...
2
by: =?iso-8859-9?B?RGlu52F5IEFr5/ZyZW4=?= | last post by:
Following function void mdelr(int *ar1, int a, int b, int d ) { int i,j,tmp; int *temp; for (i=0; i<a; i++) {
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
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,...
0
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,...
0
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...
0
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...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

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.