Search code examples
c++c++11deep-copystdstringc++98

C++ Fastest way to pass a std::string?


Note I am asking this as a std::string-specific question, not a general how to pass an object one.

I would delete this question but I am not allowed to because of the answers it has. I believe the answers may have tended to degenerate into answering the more general question of "What's the best way to pass an object in C++?" There are many duplicates of these more general answers on stack overflow even if this precise question may not itself be a dup. This degeneration may be because the question is an ill-posed one, and there is nothing special about the std::string class. This question is not highly up-voted, which suggests it is not interesting. My bad in that case. Perhaps a mod will see this black text, take pity on me and kill this question.

Which of the following signatures represents the fastest way to pass a non-const std::string instance into a function which does not modify it, taking into account the overall overhead of the call at the calling site including whether a deep-copy of the underlying character array would be generated prior to the call?

extern void eat_string_by_value          (std::string s);
extern void eat_const_string_by_value    (const std::string s);
extern void eat_string_by_reference      (std::string& s);
extern void eat_const_string_by_reference(const std::string& s);

Note I am asking this as a std::string-specific question, not a general how to pass an object one. In particular, my question is spurred by:

  • std::string handle-body implementation: Do any of the signatures imply a deep copy of the string body and its backing character array at the calling site?
    • Note the difference between copying the handle (which should be lightweight) and copying the body (which would involve memory allocation).
  • C++98 versus C++>=11: Is there a different answer either side of this version divide?

I do not see my question as a duplicate of this previous one which was itself marked as a duplicate of a general object passing one< Pass arguments as std::string or const std::string&? > because of these type-specific detailed points.

An interesting answer on a related question:


Solution

  • Which of the following signatures represents the fastest way to pass a non-const std::string instance into a function which does not modify it, taking into account the overall overhead of the call at the calling site including whether a deep-copy of the underlying character array would be generated prior to the call?

    It depends. There is no single way which is best for all cases, in all regards.

    The primary variables:

    • what are you passing? The length of the strings can affect which form will outperform the others.
    • the compiler
    • the compiler options and language standard
    • the standard library
    • would a copy be required at the callsite?
    • what happens to the string in the function?
    • passing by value can open up some possibilities for optimization, but the cost to copy is often higher.

    There is not one answer/signature which is ideal for every case.

    std::string handle-body implementation: Do any of the signatures imply a deep copy of the string body and its backing character array at the calling site?

    Some implementations used COW (Copy On Write), but that is no longer valid in C++11. Passing values will require a copy. The copy may be fast (=no heap allocation) for short strings, if SSO is implemented by your library.

    C++98 versus C++>=11: Is there a different answer either side of this version divide?

    As mentioned above, COW is no longer valid. You may see very different performance characteristics.