Without changing a single line of code, simply switching to C++11 might make your code faster by recompiling
std::vector<std::string> create() {
std::vector<std::string> coll;
coll.reserve(3); // +1
std::string s = "data"; // +1
coll.push_back(s); // +1
coll.push_back(s+s); // +2, -1, creates and destroy temporary
coll.push_back(s); // +1
return coll; // +4/ -1 for s, -4 for coll, compiler might not deep copy
}
std::vector<std::string> v = create();10 allocation and 6 deallocations for creating a vector with 3 elements. If we would have constructed them in place, we would have done 4 allocations and no deallocations.
Notice that the C++ standards has an "as-if" rule, that gives a compiler the possibility to perform all transformations it wants as long as the "observable behaviour" is unaffected. As the standard does not mention anything about performance, compiler authors take advantage of that to optimize the code as much as possible.
The C++ standard also gave the possibility to change the observable behaviour in some situations, one of those is when copying values. Compilers are permitted (but not obliged, as with all optimisations) to assume that the copy constructor copies, and thus optimize temporaries away.
Such techniques are commonly referred as copy elision, and are supported by the mainstream compiler long ago.
Thus, with a more optimistic analysis
std::vector<std::string> create() {
std::vector<std::string> coll;
coll.reserve(3); // +1
std::string s = "data"; // +1
coll.push_back(s); // +1
coll.push_back(s+s); // +2, -1, creates and destroy temporary
coll.push_back(s); // +1
return coll; // -1 for s
}
std::vector<std::string> v = create();6 allocation and 2 deallocations. Better than before, still not optimal, and not garanteed by the language, even if tested compilers are consistent.