0c8ea3c0   
   From: ulrich.eckhardt@dominolaser.com   
      
   Am 10.04.2012 11:18, schrieb rossmpublic@gmail.com:   
   > I have a very simple question that I have been unable to find a   
   > satisfactory answer. The question is why do I need to manually   
   > optimize my functions using const references?   
   >   
   > For example:   
   >   
   > // Optimized passing of string parameter   
   > Widget(std::string const & name);   
   > SetName(std::string const & name);   
   >   
   > // Non-optimized passing of string parameter   
   > Widget(std::string name);   
   > SetName(std::string name);   
      
   Even worse:   
      
   // optimized passing of int parameter   
   void foo(int i);   
   // pessimized passing of int parameter   
   void foo(int const& i);   
   // probably pessimized passing of pair   
   void bar(std::pair const& p);   
   // and what about this here??   
   SetName(std::string name) { this->name.swap(name); }   
      
   The performance of course depends on the actual implementation, but in   
   common implementations a reference is just a "self-dereferencing   
   pointer", so a reference requires another level of indirection. Also,   
   any function can cheat and const_cast, so a calling function must not   
   assume that the call doesn't modify the passed object. Making informed   
   predictions requires looking at the implementation of the function,   
   which is the reason that many modern compiler perform optimizations   
   across translation-unit boundaries.   
      
   Note that the thing with the int and pair above is something I learned   
   from micro-optimizing some code. Certain code. On one particular   
   platform. In a very tight loop. I don't claim that this is universally   
   the most performant way.   
      
      
   > I understand that with the latter notation there is an additional   
   > copy involved on most compilers, but why is that exactly? Why is it   
   > that the compiler (as smart as it is today) is unable to optimize   
   > away the additional copy?   
      
   I think that it is possible to elide copying. Passing an object into a   
   function is very similar to returning it from a function, and RVO is   
   commonplace nowadays. If the compiler knows that an object is not   
   modified inside a function, it can exploit that knowledge.   
      
      
   > Why should I be writing optimization code into my interfaces?? This   
   > seems very wrong to me.   
      
   I agree. The compiler should figure out the fastest way itself. This   
   isn't trivial though:   
      
    struct weird {   
    string X;   
    void set_with_brackets(string x) {   
    X = "<";   
    X += x;   
    X += ">";   
    }   
    };   
    weird thing = { "argh!" };   
    thing.set_with_brackets(thing.X);   
      
   If you change the parameter to a reference, this code suddenly changes   
   its result! The "const&" makes sure that you don't accidentally modify   
   it through this reference, it doesn't guarantee that the object itself   
   isn't changed by other means.   
      
      
   > I understand that the language probably cannot guarantee that there   
   > will not be a copy but why haven't the compilers stepped up with this sort   
   > of optimization as was done with return value optimization?   
      
   I guess that there are two reasons:   
   1. People are used to it, the "const&" is something that the brain has   
   learned to ignore. Further, this is only written in one or two places.   
   2. If you pass the object to modify as reference to the function, which   
   is a common way to avoid copying, you sacrifice the ability to chain   
   functions, you need two lines of code, you can't declare the object   
   const etc. This hurts much more than declaring the passed parameter as   
   reference to const in two places!   
      
      
   Uli   
      
      
   --   
    [ See http://www.gotw.ca/resources/clcm.htm for info about ]   
    [ comp.lang.c++.moderated. First time posters: Do this! ]   
      
   --- SoupGate-Win32 v1.05   
    * Origin: you cannot sedate... all the things you hate (1:229/2)   
|