Copy Constructors and Operators

Performance: Deep vs Shallow Copying

What are the performance implications of deep copying versus shallow copying?

Abstract art representing computer programming

The choice between deep copying and shallow copying can have significant performance implications in C++. Understanding these implications is crucial for writing efficient code, especially when dealing with large objects or frequently copied data structures.

Shallow Copying

Shallow copying involves copying only the immediate data members of an object. For primitive types and pointers, this means copying the values directly. For pointers, the address is copied, not the pointed-to data.

Performance characteristics:

  • Fast: Only copies the direct members of the object.
  • Low memory usage: Doesn't duplicate underlying data for pointer members.
  • Constant time complexity: O(1)O(1) regardless of object size.

Example of shallow copying:

#include <chrono>
#include <iostream>

class ShallowPlayer {
public:
  ShallowPlayer(int* hp) : health(hp) {}
  int* health;
};

int main() {
  const int numCopies = 1'000'000;
  int hp = 100;

  auto start =
    std::chrono::high_resolution_clock::now();

  for (int i = 0; i < numCopies; ++i) {
    ShallowPlayer original(&hp);
    // Shallow copy
    ShallowPlayer copy = original;
  }

  auto end =
    std::chrono::high_resolution_clock::now();
  std::chrono::duration<double> diff = end -
    start;

  std::cout << "Time to perform " << numCopies
    << " shallow copies: " << diff.count() << "s";
}
Time to perform 1000000 shallow copies: 0.0021545s

Deep Copying

Deep copying involves creating a new copy of all data owned by the object, including dynamically allocated memory that the object might be pointing to.

Performance characteristics:

  • Slower: Needs to allocate new memory and copy all underlying data.
  • Higher memory usage: Duplicates all data, leading to increased memory consumption.
  • Linear time complexity: O(n)O(n) where n is the size of the underlying data.

Example of deep copying:

#include <chrono>
#include <iostream>
#include <memory>

class DeepPlayer {
public:
  DeepPlayer(int hp) : health(
    std::make_unique<int>(hp)) {}

  DeepPlayer(const DeepPlayer& other)
    : health(
      std::make_unique<int>(*other.health)) {}

  std::unique_ptr<int> health;
};

int main() {
  const int numCopies = 1'000'000;

  auto start =
    std::chrono::high_resolution_clock::now();

  for (int i = 0; i < numCopies; ++i) {
    DeepPlayer original(100);
    DeepPlayer copy = original; // Deep copy
  }

  auto end =
    std::chrono::high_resolution_clock::now();
  std::chrono::duration<double> diff = end -
    start;

  std::cout << "Time to perform " << numCopies
    << " deep copies: " << diff.count() << "s";
}
Time to perform 1000000 deep copies: 0.449998s

Running both these programs will show a significant performance difference, with shallow copying being much faster.

Considerations

  • Shallow copying is faster but can lead to issues with shared mutable state.
  • Deep copying is safer for managing independent objects but comes with a performance cost.
  • The choice depends on your specific use case. Sometimes, a mix of both approaches (like copy-on-write) can be optimal.
  • For large objects or collections, the performance difference can be substantial and should be carefully considered in performance-critical code.

Remember, the right choice depends on your specific requirements for correctness, memory usage, and performance. Always profile your code to make informed decisions about copying strategies.

Answers to questions are automatically generated and may not have been reviewed.

3D art showing a progammer setting up a development environment
Part of the course:

Intro to C++ Programming

Become a software engineer with C++. Starting from the basics, we guide you step by step along the way

Free, unlimited access

This course includes:

  • 59 Lessons
  • Over 200 Quiz Questions
  • 95% Positive Reviews
  • Regularly Updated
  • Help and FAQ
Free, Unlimited Access

Professional C++

Comprehensive course covering advanced concepts, and how to use them on large-scale projects.

Screenshot from Warhammer: Total War
Screenshot from Tomb Raider
Screenshot from Jedi: Fallen Order
Contact|Privacy Policy|Terms of Use
Copyright Š 2024 - All Rights Reserved