3

In my programm I have a function that takes multiple vectors as arguments. I used to pass them as normal vectors so like the definition of the function starts like this:

void do(std::vector<int> a, std::vector<int> b, std::vector<int> c){

and the call looks like this:

do(d, e, f);

but I want my code to be as fast as possible so I wondered whether passing not the vectors but pointers to the vectors would be faster. So the definition of the funtion would look something like this:

void do(std::vector<int> *a, std::vector<int> *b, std::vector<int> *c){

and the call like this:

do(&d, &e, &f);

Does this change make a difference in performance? If yes: positive or negative and is it a big difference if my vectors contain just 3 elements?

kamelfanger83
  • 97
  • 1
  • 7
  • 14
    You have the right idea but prefer references over pointers in cases like these. – mediocrevegetable1 Jul 29 '21 at 14:43
  • 4
    if the `vector`s are not going to be changed by `do`, pass them by `const` reference (`const std::vector &a`) If you always start with the highest restrictions on what you can do with an object the compiler can pick off mistakes for you more easily. Plus restrictions on usage often make it easier for the compiler to optimize. – user4581301 Jul 29 '21 at 14:50
  • 1
    In the `do` function, what do you do with those vectors you're passing in? Do you still make copies of them inside the function? Also, `do` is a keyword in C++. You do not want to call your function `do`. – PaulMcKenzie Jul 29 '21 at 15:22
  • 1
    Does this answer your question? [How to pass objects to functions in C++?](https://stackoverflow.com/questions/2139224/how-to-pass-objects-to-functions-in-c) – pptaszni Jul 29 '21 at 15:24

2 Answers2

9

Consider the C++ Core Guideline F.16: For “in” parameters, pass cheaply-copied types by value and others by reference to const.

What is cheap and what is expensive to pass by copy depends on some factors. A good rule of thumb is to pass anything as big as a pointer or smaller by value and anything bigger by reference. A std::vector is certainly better passed by const reference instead of making a copy.

You should only pass a pointer instead of a reference when passing a nullptr is a valid parameter. When the caller should always pass a vector and never not a vector then you should prefer references over pointers. References cannot be null, they always refer to an object.


Note that sometimes there is no point in avoiding the copy when the function makes a copy of the argument anyhow. Consider:

 void foo(const std::vector<int>& a) { 
      auto copy = a;
      // ...
 }

Then with

 void foo(std::vector<int> a) {
      // a is already a copy
      // ...
 }

it is more obvious that the function is making a copy, while nothing is saved by passing by reference.

user4581301
  • 33,082
  • 7
  • 33
  • 54
463035818_is_not_an_ai
  • 109,796
  • 11
  • 89
  • 185
  • 1
    I think it also depends on what is being done inside the function itself. If the function still makes a copy of the argument, then possibly passing by value would be more optimal than doing a hand-coded copy inside the function. – PaulMcKenzie Jul 29 '21 at 15:26
  • @PaulMcKenzie ...unless that copy is returned from the function in which case afaik its better to make the copy in the function to get nrvo. Yes you are right, i tried to keep it simple – 463035818_is_not_an_ai Jul 29 '21 at 15:29
0

In terms of optimization, you should avoid passing complex types by value. Always use a pointer or reference. As we can see in example, passing by value is much much slower.

Example: https://quick-bench.com/q/C7732NYi7-gh0PgleKAGo8qmKZA

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Deumaudit
  • 978
  • 7
  • 17