Code Comments

Programming Forum and web based access to our favorite programming groups.
For Programmers: Free Programming Magazines | New: Database administration forum
Registration is free! Edit your profileCalendarFind other membersFrequently Asked QuestionsSearch -> 
Post New Thread











Thread
Author

Return value optimization
Hi NG

A few days ago there was a thread in comp.lang.c++.moderated with the
subject "Return versus Side-Effect". The OP asked whether to use "return by
value" or an additional parameter of type "C&" which will be overwritten
with a result.
The most posters advised the OP to use the version with the return value. No
only for aesthetic reasons but also for performance reasons because of the
return value optimization.
I wrote a little sample program to test their assertion.
For aesthetic reasons I prefer the "return by value" version. But I found
out that for performance reasons both versions are necessary. It depends on
how you call the function. Sometimes the "return by value" is faster than
the "out-parameter" version and sometimes the other way around. Can you
confirm my conclusion?

Best regards,
Chris





Here is my test code:


#include <iostream>
using std::cout;

#include <iostream>
using std::cout;

class MyString
{
public:
MyString() : value(NULL) { cout << "ctor 0\n"; }
MyString(const char*);
MyString(const MyString&);
~MyString() { delete[] value; }

MyString& operator=(const char* newValue);
MyString& operator=(const MyString&);

private:
char* value;
};


MyString::MyString(const char* newValue)
{
cout << "ctor 1\n";
if (newValue == NULL) {
value = NULL;
} else {
int length = strlen(newValue);
value = new char[length + 1];
strcpy(value, newValue);
}
}


MyString::MyString(const MyString& other)
{
cout << "copy ctor\n";
if (other.value == NULL) {
value = NULL;
} else {
int length = strlen(other.value);
value = new char[length + 1];
strcpy(value, other.value);
}
}


MyString& MyString::operator=(const char* newValue)
{
cout << "op =0\n";
if (value != NULL) {
delete[] value;
} // if

if (newValue == NULL) {
value = NULL;
} else {
int length = strlen(newValue);
value = new char[length + 1];
strcpy(value, newValue);
}
return *this;
}


MyString& MyString::operator=(const MyString& other)
{
cout << "op =1\n";
if (this == &other) {
return *this;
} // if

if (value != NULL) {
delete[] value;
} // if

if (other.value == NULL) {
value = NULL;
} else {
int length = strlen(other.value);
value = new char[length + 1];
strcpy(value, other.value);
}

return *this;
}


MyString returnByVal()
{
MyString ret("return value");
return ret;
}


void returnByParam(MyString& out)
{
out = "return value";
}



int main()
{
// First test case where the out parameter is faster.
cout << "Before returnByVal()\n";
MyString str1;
str1 = returnByVal();
cout << "\nBefore returnByParam()\n";
MyString str2;
returnByParam(str2);
cout << "Finished test 1\n\n\n";

// Second test case where return by value is faster.
cout << "Before returnByVal()\n";
MyString str3 = returnByVal();
cout << "\nBefore returnByParam()\n";
MyString str4;
returnByParam(str4);
cout << "Finished test 2\n";
}





The output is the following:

Before returnByVal()
ctor 0
ctor 1
op =1

Before returnByParam()
ctor 0
op =0
Finished test 1


Before returnByVal()
ctor 1

Before returnByParam()
ctor 0
op =0
Finished test 2


In the first test case the "out-parameter" version is faster.
In the second test case the "return by value" version is faster.



Report this thread to moderator Post Follow-up to this message
Old Post
Christian Meier
04-03-08 11:17 AM


Re: Return value optimization
On Apr 3, 10:15 am, "Christian Meier" <chris@no_spam.com> wrote:
> Hi NG
>
> A few days ago there was a thread in comp.lang.c++.moderated with the
> subject "Return versus Side-Effect". The OP asked whether to use "return b
y
> value" or an additional parameter of type "C&" which will be overwritten
> with a result.
> The most posters advised the OP to use the version with the return value. 
No
> only for aesthetic reasons but also for performance reasons because of the
> return value optimization.
> I wrote a little sample program to test their assertion.
> For aesthetic reasons I prefer the "return by value" version. But I found
> out that for performance reasons both versions are necessary. It depends o
n
> how you call the function. Sometimes the "return by value" is faster than
> the "out-parameter" version and sometimes the other way around. Can you
> confirm my conclusion?
> [...]

Change this:

>
> MyString& MyString::operator=(const MyString& other)
> {
>     cout << "op =1\n";
>     if (this == &other) {
>         return *this;
>     } // if
>
>     if (value != NULL) {
>         delete[] value;
>     } // if
>
>     if (other.value == NULL) {
>         value = NULL;
>     } else {
>         int length = strlen(other.value);
>         value = new char[length + 1];
>         strcpy(value, other.value);
>     }
>     return *this;
> }

Into:

MyString& MyString::operator=(MyString other)
{
value = other.value;
other.value = 0;
cout << "op =1\n";
return *this;
}

the output doesn't change, but now the "op=1" operation is quite
inexpensive.

--
gpd

Report this thread to moderator Post Follow-up to this message
Old Post
gpderetta
04-03-08 11:17 AM


Re: Return value optimization
In article <6a853$47f49214$3e024b42$18038@news.hispeed.ch>,
Christian Meier <chris@no_spam.com> wrote:
>

Deleted String class too complex to best illustrate NVRO.
All you need is a very simply class the cout
Constuctor/Copyconstructor/operator=.  All the rest obfuscate.

>
>int main()
>{
>    // First test case where the out parameter is faster.
>    cout << "Before returnByVal()\n";
>    MyString str1;

You create the object using the default constructor for no reason.
If you tell the compiler that it must create a default initialised
object then that is what it does even if a human code reviewer would
question why you felt the need to default initialise it and
immediately assign to it.  The compiler can't send you an email
asking: "Are you sure that's really what you want to do?"

>    str1 = returnByVal();

then assign to it

>    cout << "\nBefore returnByParam()\n";
>    MyString str2;
>    returnByParam(str2);
>    cout << "Finished test 1\n\n\n";
>
>    // Second test case where return by value is faster.
>    cout << "Before returnByVal()\n";
>    MyString str3 = returnByVal();

Here you create and initialise correctly all at once.  That's better

>    cout << "\nBefore returnByParam()\n";
>    MyString str4;
>    returnByParam(str4);
>    cout << "Finished test 2\n";
>}
>

>The output is the following:
>
>Before returnByVal()
>ctor 0
>ctor 1
>op =1
>
>Before returnByParam()
>ctor 0
>op =0
>Finished test 1
>
>
>Before returnByVal()
>ctor 1

And your test shows that there are less methods called.

>Before returnByParam()
>ctor 0
>op =0
>Finished test 2
>
>
>In the first test case the "out-parameter" version is faster.
>In the second test case the "return by value" version is faster.

Hmm, maybe.  You have only traced number of methods called.  Not speed
so you are assuming that this is faster.  It might not be and it might
not be relevant.

Yan

Report this thread to moderator Post Follow-up to this message
Old Post
Yannick Tremblay
04-03-08 11:17 AM


Sponsored Links




Last Thread Next Thread Next
Search this forum -> 
Post New Thread

C++ archive

Show a Printable Version Send to friend Email This Page to Someone! subscribe to this thread Receive updates to this thread
Computer Consultants
Programming Jobs
Visual Basic Controls
SQL Server Programming
Webservices
Java Security
Visual Studio
C# Programming
Visual J++
Software engineering
Open source Software
Perl Programming
PHP Programming
ASP Programming
ASP .NET Programming
Visual Basic Programming
Windows Scripting Host
Java Programming
Java Help
Java Beans
VBScript
Cobol
MAC Applications
Unix Programming
Forum Jump:
All times are GMT. The time now is 06:45 AM.

 
Free MCSE Braindumps | Real Estate Topics

Programming forum archive

Copyrights CodeComments.com 2004 - 2006

Powered by vBulletin Copyright 2000-2006 Jelsoft Enterprises Limited.