Opening Scenario

You're adding a function to an analytics service. It takes a 200 MB dataframe-ish structure, filters it, and returns the filtered result.

Four of your coworkers write four different signatures, all "correct":

# Python
def filter_rows(df, pred): ...                    # dev A

# C++
std::vector<Row> filter_rows(std::vector<Row> df, Pred pred);        // dev B — takes by value
std::vector<Row> filter_rows(const std::vector<Row>& df, Pred pred); // dev C — takes by ref
std::vector<Row> filter_rows(std::vector<Row>&& df, Pred pred);      // dev D — takes by rvalue ref

Dev B's Python test passes. Dev B's C++ test also passes — but a profiler shows the function is allocating another 200 MB per call. At 1,000 calls/second, that's 200 GB/s of allocation. Something is very different between Python and C++ in the same-looking code, and something is very different between B, C, and D in the C++ versions.

What is copying actually costing you, when can you move instead, and when should you just share?

In the full tutorial

  • Question Progression
  • When to Reach for This

Glossary history

Click dotted jargon to save explanations here.