tags:

views:

188

answers:

5

I am unsure about how function calls are translated and I am afraid that passed variables are copied into local variables when they don't need to be. I could avoid unnecessary copying by using global variables, but that cannot be a good solution...

1) When variables are not changed in the target function, would it be better to pass them as pointers, references, or const?

void fkt1(int i, int j){
  do_something();
  printf("%d", i+j);
}

int main(){
  int i = 5;
  int j = 6;
  fkt1(i, j);
}

2) Is it expensive to pass variables to a function when they are not used within it. E.g., to keep a common interface, such as:

template <typename T>
void fkt2(T a, T b, int len = -1){ 
  do_something();
  printf("%d", a+b);
}

template<>
void fkt2<char*>(char* a, char* b, int len){
  do_something();
  strcpy(a+len, b);
  printf("%s", a);
}

or

class base{
public:
  virtual bool calc(int i, int j, int k, int l) = 0;
  base *next1;
  base *next2;
}

class derived1 : public base{
public:
  bool calc(int i, int j, int k, int l){
    return (next1->calc(int i, int j, int k, int l) || 
            next2->calc(int i, int j, int k, int l))
  }
}    

class derived2 : public base{
public:
  bool calc(int i, int j, int k, int l){
    return (return i+j > 5)
  }
}    

class derived3 : public base{
public:
  bool calc(int i, int j, int k, int l){
    return (return j*k < l)
  }
}    

Comments are much appreciated.

+17  A: 

Don't worry about the performance issues at this point.

Focus on the algorithmic cost of your function, not the trivial things: guessing performance issues is a bad idea.

If you really encounter performance issues and have maintainable code, it will still be time to improve it.

Now to really answer the question:

You may pass const references when the object you have to pass really shouldn't be copied. If you have to pass integers, or simple structs (aka. small types), using a const reference or even a pointer is probably too much work: you will clutter the code with uneeded complexity were the compiler would probably have optimized things anyway.

ereOn
Not to mention, passing a pointer is no less work than passing an integer of the same size!
caf
+2  A: 

If you're dealing with complex types, like structs or classes, then it depends on the copy constructor. If it does a deep copy, then passing a copy is likely fairly expensive, and you should use a reference or pointer instead. Even if you only do a shallow copy, there might be a small performance benefit from using a reference, but it's minimal at best.

In general, it just doesn't matter; what matters is what is done in the function, and the cost of passing parameters one way or another is neglible. Passing parameters as a copy, a pointer or a reference should depend on what you need to do with that parameter, not which is faster.

Michael Madsen
+4  A: 

See this answer for how to pass objects to functions in C++.

Otherwise I fully agree with ereOn. First write correct, simple, and easy-to-maintain code, and limit performance consideration to application design and algorithms. If you later find you have a performance problem, measure first, then try to improve, then measure again.

sbi
+2  A: 

Global variables may actually hurt performance due to cache locality. But you should avoid them just for being global variables, performance notwithstanding.

1) If variables are not changed in a function then pass them as const references in C++. In C just pass by value so the original argument can't be changed. This is for good programming practice, not performance.

2) Passing an unused variable will still require the call stack to be built with it included. However, many processors have calling conventions that just pass parameters in registers. Let the compiler do the optimization; it's good at it.

The performance issues you're pondering are trivial given today's processor speeds and compiler capabilities. Don't design your code with parameter constraints based on performance fears. It will only degrade the quality of your design.

Amardeep
A: 

Function calls (including parameter passing) nowadays comes with relatively little cost. This cost is e.g neglectable if you have any other complicated task such as printf or so in your function.

To get the best, you could try to hold your functions definitions in include files and flag them with inline. This is supported in C++ and C99 and should do the best possible in most common circumstances.

Jens Gustedt
Except that inlining sometimes makes gargantuan functions that won't fit in cache, thus becoming a pessimization. It's all about measurement.
Nathon
@Nathon: Except that's out of the programmers control. You have to use implementation-specific extensions to tell a compiler *not* to inline functions, and of course the only smart way to know which functions to do that to is after profiling and looking at the assembly.
GMan