Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it a premature optimization to use std::move()?

Tags:

c++

c++11

Suppose I have the following code:

int main() {     std::vector<std::string> strs;      std::string var("Hello World");     // Make some modifications to 'var'     strs.push_back(std::move(var)); } 

The part of the sample I want to point out is the usage of std::move(). Basically I'm worried about a copy on the push_back() call. Suppose the string I'm adding is really big. I'm still learning C++11 r-value references, so I'm not sure how the compiler would optimize away the copy (if at all) without the std::move().

Could anyone explain if this is a premature optimization (forcing moves in all cases where you want to avoid copies, in general)? If so, what patterns should I expect the compiler to follow (or most likely follow) that would result in an optimized and automatic move here?

EDIT

I want to add that I understand how automatic moves happen on function return values, because NRVO/RVO applies. The specific example I gave here wouldn't apply RVO, so I'm uncertain.

like image 846
void.pointer Avatar asked Aug 27 '14 14:08

void.pointer


People also ask

When should we use std :: move?

In C++11, std::move is a standard library function that casts (using static_cast) its argument into an r-value reference, so that move semantics can be invoked. Thus, we can use std::move to cast an l-value into a type that will prefer being moved over being copied.

What happens when you to std :: move?

std::move is used to indicate that an object t may be "moved from", i.e. allowing the efficient transfer of resources from t to another object. In particular, std::move produces an xvalue expression that identifies its argument t . It is exactly equivalent to a static_cast to an rvalue reference type.

What is premature optimization in C#?

Usually premature optimizations are made during the development process without using any profiling tools to find bottlenecks in the code. In many cases the optimization will make the code harder to maintain and sometimes also increases the development time, and therefore the cost of the software.

Is Premature optimization good?

Premature optimization, at the microscopic level, is usually a bad idea. This does not suggest, however, that engineers should not be concerned about application performance. The fallacy that "premature optimization" is the same thing as "concern about performance" should not guide software development.


2 Answers

I'm not sure how the compiler would optimize away the copy (if at all) without the std::move().

Only a very clever compiler could optimise that away, so if the copy could be expensive (e.g. a very long string) then it is better to move it.

Without the move the code is effectively a sequences of calls to:

strlen  // count "Hello World" malloc  // allocate memory for string var strcpy  // copy data into var malloc  // re-allocate vector free    // deallocate old vector malloc  // allocate new string strcpy  // copy from var to new string free    // destroy var 

With the move it becomes:

strlen  // count "Hello World" malloc  // allocate memory for string var strcpy  // copy data into var malloc  // re-allocate vector free    // deallocate old vector 

In theory a smart compiler could do that transformation automatically, but for the compiler to see through all the layers of abstraction introduced by the constructors and destructor and the vector member functions is quite difficult, so proving that the code could be transformed to remove a malloc and free is complicated.

like image 175
Jonathan Wakely Avatar answered Sep 23 '22 11:09

Jonathan Wakely


The other answers focus too much on the technical aspects of the question for my taste, so I will try to give a more general answer.

In short: No, using a "trick" like std::move in the way it's described in the question isn't a premature optimization. Not using std::move when it can be used is fine too, unless the code is already known to be performance critical.

The need to avoid premature optimization is sometimes understood as "don't optimize, until you can prove it's necessary", but I prefer to read it as: "don't waste time solving problems unless you know they need to be solved".

Premature optimizations require spending effort in order to optimize what may not need to be optimized, and usually transform a simple problem into a complex problem while doing so. From that perspective, I would classify any long pondering of the question itself as premature optimization.

A related example: People working in performance critical code will often pass arguments as const references ( const std::string& ). Because that's what they are used to do, they will use the same pattern in code that isn't performance critical, even though they could just use pass-by-copy ( const std::string, or even std::string ). That isn't a premature optimization either.

like image 28
Peter Avatar answered Sep 22 '22 11:09

Peter