Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Speed of passing a string by value vs. const reference

Reply
Thread Tools

Speed of passing a string by value vs. const reference

 
 
K. Frank
Guest
Posts: n/a
 
      05-27-2013
Hello Group!

Thanks to all for your various replies. This is very
much the kind of guidance I was looking for.


K. Frank
 
Reply With Quote
 
 
 
 
James Kanze
Guest
Posts: n/a
 
      05-29-2013
On Saturday, May 25, 2013 7:22:49 PM UTC+1, K. Frank wrote:
> Let's say I have a function that takes a std::string as an
> argument. Are there any rules of thumb for when is is likely
> to be more efficient to pass the string by value instead of
> const reference?


> I understand that the specific details matter such as how big
> the string is and how often it is accessed in the function.
> I'm wondering if there are any rough guidelines for which
> approach is likely to be faster.


The ubiquitous rule is to pass class types by reference to
const, other types by value. Since std:;string is a class type,
convention says to pass it by reference to const, even if with a
well written string class, it won't make a significant
difference.

--
James
 
Reply With Quote
 
 
 
 
SG
Guest
Posts: n/a
 
      05-30-2013
On May 29, 11:46*pm, James Kanze wrote:
> The ubiquitous rule is to pass class types by reference to
> const, other types by value. *Since std:;string is a class type,
> convention says to pass it by reference to const, even if with a
> well written string class, it won't make a significant
> difference.


Some rules are now outdated in the light of move semantics.
 
Reply With Quote
 
Andreas Dehmel
Guest
Posts: n/a
 
      05-30-2013
On Thu, 30 May 2013 02:06:37 -0700 (PDT)
SG <(E-Mail Removed)> wrote:

> On May 29, 11:46*pm, James Kanze wrote:
> > The ubiquitous rule is to pass class types by reference to
> > const, other types by value. *Since std:;string is a class type,
> > convention says to pass it by reference to const, even if with a
> > well written string class, it won't make a significant
> > difference.

>
> Some rules are now outdated in the light of move semantics.


Nonsense. For container types, a move still implies swapping at
least 2-3 pointer-sized members and while this is certainly orders
of magnitude faster than copying the whole thing, there's no way
this'll be faster than simply dereferencing a pointer.



Andreas
--
Dr. Andreas Dehmel Ceterum censeo
FLIPME(ed.enilno-t@nouqraz) Microsoft esse delendam
http://www.zarquon.homepage.t-online.de (Cato the Much Younger)

 
Reply With Quote
 
Tiib
Guest
Posts: n/a
 
      05-30-2013
On Thursday, 30 May 2013 16:28:53 UTC+3, Andreas Dehmel wrote:
> On Thu, 30 May 2013 02:06:37 -0700 (PDT)
> SG <(E-Mail Removed)> wrote:
> > On May 29, 11:46*pm, James Kanze wrote:
> > > The ubiquitous rule is to pass class types by reference to
> > > const, other types by value. *Since std:;string is a class type,
> > > convention says to pass it by reference to const, even if with a
> > > well written string class, it won't make a significant
> > > difference.

> >
> > Some rules are now outdated in the light of move semantics.

>
> Nonsense. For container types, a move still implies swapping at
> least 2-3 pointer-sized members and while this is certainly orders
> of magnitude faster than copying the whole thing, there's no way
> this'll be faster than simply dereferencing a pointer.


So what? Parameter is passed once but that dereference may happen
several times during function call. It may add up costing more.
 
Reply With Quote
 
Tiib
Guest
Posts: n/a
 
      05-30-2013
On Thursday, 30 May 2013 22:21:56 UTC+3, Paavo Helde wrote:
> Tiib <(E-Mail Removed)> wrote in news:9af31fe2-0eba-4788-96fd-
> > So what? Parameter is passed once but that dereference may happen
> > several times during function call. It may add up costing more.

>
> It is trivial for the compiler to optimize out this extra dereference as
> C++ references cannot be reseated. Or have I misunderstood something?


All optimizations are trivial. It can be optimized by cashing the pointer
in some register. Fine if compiler can reserve a register for a parameter
but registers are often quite limited resource. I was responding to
"nonsense, there's no way" when actual measurements show that there is.
 
Reply With Quote
 
SG
Guest
Posts: n/a
 
      05-31-2013
On May 30, 3:28*pm, Andreas Dehmel wrote:
> On Thu, 30 May 2013 02:06:37 -0700 (PDT)
> SG <(E-Mail Removed)> wrote:
> > On May 29, 11:46*pm, James Kanze wrote:
> > > The ubiquitous rule is to pass class types by reference to
> > > const, other types by value. *Since std:;string is a class type,
> > > convention says to pass it by reference to const, even if with a
> > > well written string class, it won't make a significant
> > > difference.

>
> > Some rules are now outdated in the light of move semantics.

>
> Nonsense. For container types, a move still implies swapping at
> least 2-3 pointer-sized members and while this is certainly orders
> of magnitude faster than copying the whole thing, there's no way
> this'll be faster than simply dereferencing a pointer.


Compare

string flip(string const& cref) {
string result = cref; // explicit copy,
// might be unnecessary
reverse(result.begin(),result.end());
return result; // NRVO applicable
}

with

string flip(string temp) { // temp might be move-constructed or
// even constructed directly via
// copy/move elision
reverse(temp.begin(),temp.end());
return temp; // implicitly moved
}

You might want to test this with a dummy-string class and count the
number of copy and move constructions in the following example:

int main() {
string foo = flip(flip(flip(flip("hello"))));
}

So, no, it's not nonsense. In situations where you have the choice
between pass-by-value and pass-by-ref-to-const for class types, the
rule "always take a ref-to-const" is obviously not correct anymore.
Note that I'm not saying "always use pass-by-value" either.

You might also want to check Dave Abrahams' article about this with
the provoking title: "Want speed? Pass by value.":
http://cpp-next.com/archive/2009/08/...pass-by-value/

Cheers!
SG
 
Reply With Quote
 
Andreas Dehmel
Guest
Posts: n/a
 
      05-31-2013
On Thu, 30 May 2013 17:55:04 -0700 (PDT)
SG <(E-Mail Removed)> wrote:

> On May 30, 3:28*pm, Andreas Dehmel wrote:
> > On Thu, 30 May 2013 02:06:37 -0700 (PDT)
> > SG <(E-Mail Removed)> wrote:
> > > On May 29, 11:46*pm, James Kanze wrote:
> > > > The ubiquitous rule is to pass class types by reference to
> > > > const, other types by value. *Since std:;string is a class type,
> > > > convention says to pass it by reference to const, even if with a
> > > > well written string class, it won't make a significant
> > > > difference.

> >
> > > Some rules are now outdated in the light of move semantics.

> >
> > Nonsense. For container types, a move still implies swapping at
> > least 2-3 pointer-sized members and while this is certainly orders
> > of magnitude faster than copying the whole thing, there's no way
> > this'll be faster than simply dereferencing a pointer.

>
> Compare
>
> string flip(string const& cref) {
> string result = cref; // explicit copy,
> // might be unnecessary
> reverse(result.begin(),result.end());
> return result; // NRVO applicable
> }
>
> with
>
> string flip(string temp) { // temp might be move-constructed or
> // even constructed directly via
> // copy/move elision
> reverse(temp.begin(),temp.end());
> return temp; // implicitly moved
> }



You're not measuring the overhead of passing the argument one way
or another but the copy constructor in the first case, which is
a completely different issue that can easily be avoided by using
string result(cref.rbegin(), cref.rend()) rather than call reverse
on a copy. I'd call this a pathological textbook example with zero
practical relevance; one can always construct these, that doesn't
mean anything. Plus moving the argument in the second case will
not be possible if you don't call the function with a temporary,
so performance will vary considerably for rather obscure reasons
(and still be slower when not calling with a temporary).



Andreas
--
Dr. Andreas Dehmel Ceterum censeo
FLIPME(ed.enilno-t@nouqraz) Microsoft esse delendam
http://www.zarquon.homepage.t-online.de (Cato the Much Younger)

 
Reply With Quote
 
James Kanze
Guest
Posts: n/a
 
      05-31-2013
On Thursday, May 30, 2013 10:06:37 AM UTC+1, SG wrote:
> On May 29, 11:46*pm, James Kanze wrote:
> > The ubiquitous rule is to pass class types by reference to
> > const, other types by value. *Since std:;string is a class type,
> > convention says to pass it by reference to const, even if with a
> > well written string class, it won't make a significant
> > difference.


> Some rules are now outdated in the light of move semantics.


Or not. The rule was fairly arbitrary to begin with, and move semantics don't
really change that.

--
James
 
Reply With Quote
 
James Kanze
Guest
Posts: n/a
 
      05-31-2013
On Thursday, May 30, 2013 7:38:40 PM UTC+1, Tiib wrote:
> On Thursday, 30 May 2013 16:28:53 UTC+3, Andreas Dehmel wrote:
> > On Thu, 30 May 2013 02:06:37 -0700 (PDT)
> > SG <(E-Mail Removed)> wrote:
> > > On May 29, 11:46*pm, James Kanze wrote:
> > > > The ubiquitous rule is to pass class types by reference to
> > > > const, other types by value. *Since std:;string is a class type,
> > > > convention says to pass it by reference to const, even if with a
> > > > well written string class, it won't make a significant
> > > > difference.


> > > Some rules are now outdated in the light of move semantics.


> > Nonsense. For container types, a move still implies swapping at
> > least 2-3 pointer-sized members and while this is certainly orders
> > of magnitude faster than copying the whole thing, there's no way
> > this'll be faster than simply dereferencing a pointer.


> So what? Parameter is passed once but that dereference may happen
> several times during function call. It may add up costing more.


As you say: so what? The rule was always arbitrary. It had the
advantage of being simple. Move semantics don't change anything
in this respect. Logically, the rule would be pass by value,
always. But that's not the ubiquitous conventions. The
convention is what it is. It may not be perfect, but it is
ubiquitous. Thus, you need a really strong motive to violate
it.

--
James
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
is const necessary in eg int compar(const void *, const void *) lovecreatesbeauty@gmail.c0m C Programming 26 11-10-2008 09:47 PM
non-const reference and const reference George2 C++ 10 12-17-2007 02:19 PM
const vector<A> vs vector<const A> vs const vector<const A> Javier C++ 2 09-04-2007 08:46 PM
Casting int'** to 'const int * const * const' dosn't work, why? Jonas.Holmsten@gmail.com C Programming 11 07-01-2007 06:16 PM
Passing by const & and returning a temp vs passing by value and returningit Victor Bazarov C++ 25 03-23-2005 04:24 PM



Advertisments