fork download
  1. #include <iostream>
  2. #include <vector>
  3. #include <chrono>
  4. #include <utility>
  5. using CLOCK = std::chrono::high_resolution_clock;
  6. // Function that takes ownership via perfect forwarding
  7. template<typename T>
  8. void process_with_forward(T&& data) {
  9. // Use the vector directly (could also move if needed)
  10. std::vector<int> v = std::forward<T>(data);
  11. // Do some dummy computation to prevent compiler from optimizing away
  12. volatile size_t sink = v.size();
  13. (void)sink;
  14. }
  15.  
  16. // Function that always makes a copy
  17. template<typename T>
  18. void process_with_copy(T data) {
  19. std::vector<int> v = data;
  20. volatile size_t sink = v.size();
  21. (void)sink;
  22. }
  23.  
  24. int main() {
  25. constexpr size_t NUM_TESTS = 10000;
  26. constexpr size_t VECTOR_SIZE = 100000;
  27.  
  28. // Benchmark perfect forwarding version
  29. auto start_forward = CLOCK::now();
  30. for (size_t i = 0; i < NUM_TESTS; ++i) {
  31. process_with_forward(std::vector<int>(VECTOR_SIZE)); // pass rvalue
  32. }
  33. auto end_forward = CLOCK::now();
  34.  
  35. // Benchmark copying version
  36. auto start_copy = CLOCK::now();
  37. for (size_t i = 0; i < NUM_TESTS; ++i) {
  38. process_with_copy(std::vector<int>(VECTOR_SIZE)); // pass rvalue
  39. }
  40. auto end_copy = CLOCK::now();
  41.  
  42. // Output results
  43. auto microseconds_forward = std::chrono::duration_cast<std::chrono::milliseconds>(end_forward - start_forward).count();
  44. auto microseconds_copy = std::chrono::duration_cast<std::chrono::milliseconds>(end_copy - start_copy).count();
  45.  
  46. std::cout << "With perfect forwarding: " << microseconds_forward << " ms\n";
  47. std::cout << "With unnecessary copy: " << microseconds_copy << " ms\n";
  48.  
  49. return 0;
  50. }
Success #stdin #stdout 3.48s 5316KB
stdin
Standard input is empty
stdout
With perfect forwarding: 411 ms
With unnecessary copy:   3090 ms