Eugene K
Eugene K

Reputation: 3457

Is it more efficient to declare variables late?

Is it more memory or possibly computationally efficient to declare variables late?

Example:

int x;
code
..
.
.
. x is able to be used in all this code
.
actually used here
.
end

versus

code
..
.
.
.
int x;
actually used here
.
end

Thanks.

Upvotes: 3

Views: 822

Answers (4)

Write whatever logically makes most sense (usually closer to use). The compiler can and will spot things like this and produce code that makes the most sense for your target architecture.

Your time is far more valuable than trying to second guess the interactions of the compiler and the cache on the processor.


For example on x86 this program:

#include <iostream>

int main() {
  for (int j = 0; j < 1000; ++j) {
    std::cout << j << std::endl;
  }
  int i = 999;
  std::cout << i << std::endl;
}

compared to:

#include <iostream>

int main() {
  int i = 999;
  for (int j = 0; j < 1000; ++j) {
    std::cout << j << std::endl;
  }
  std::cout << i << std::endl;
}

compiled with:

g++ -Wall -Wextra -O4 -S measure.c
g++ -Wall -Wextra -O4 -S measure2.c

When inspecting the output with diff measure*.s gives:

<       .file   "measure2.cc"
---
>       .file   "measure.cc"

Even for:

#include <iostream>

namespace {
  struct foo {
    foo() { }
    ~foo() { }
  };
}

std::ostream& operator<<(std::ostream& out, const foo&) {
  return out << "foo";
}

int main() {
  for (int j = 0; j < 1000; ++j) {
    std::cout << j << std::endl;
  }
  foo i;
  std::cout << i << std::endl;
}

vs

#include <iostream>

namespace {
  struct foo {
    foo() { }
    ~foo() { }
  };
}

std::ostream& operator<<(std::ostream& out, const foo&) {
  return out << "foo";
}

int main() {
  foo i;
  for (int j = 0; j < 1000; ++j) {
    std::cout << j << std::endl;
  }
  std::cout << i << std::endl;
}

the results of the diff of the assembly produced by g++ -S are still identical except for the filename, because there are no side effects. If there were side effects then that would dictate where you constructed the object - at what point did you want the side effects to occur?

Upvotes: 9

Kerrek SB
Kerrek SB

Reputation: 477700

In general, you should declare where and when you use the variables. It improves reability, maintainability and, for purely practical reasons, memory locality.

Even if you have a large object and you declare it outside or inside a loop body, the only difference is going to be between construction and assignment; the actual memory allocation will be virtually identical, since contemporary allocators are very good at short-lived allocations.

You may even consider creating new, anonymous scopes if you have a small part of code whose variables aren't required afterwards (though that usually indicates you're better off with a separate function).

So basically, write the way it makes most logical sense, and you will usually also end up with the most efficient code; or at least you won't do any worse than you would by declaring everything at the top.

Upvotes: 5

K-ballo
K-ballo

Reputation: 81409

For fundamental types such as int, it does not matter from a performance point of view. For class types a variable definition includes a constructor invocation as well, which could be ommited if the control flow skips that variable. Furthermore, both for fundamental and class types, a definition should be delayed at least to the point were there is sufficient information to make such variable meaningful. For non default constructible class types this is mandatory; for other types it may not be but it forces you to work with uninitialized states (like -1 or other invalid values). You should define your variables as late as possible, within the minimum scope possible; it may not matter sometimes from a performance point of view but its always important design-wise.

Upvotes: 5

David Schwartz
David Schwartz

Reputation: 182893

It is neither memory nor computationally more efficient either way for simple types. For more complex types, it may be more efficient to have the contents hot in the cache (from being constructed) near where they are used. It can also minimize the amount of time the memory remains allocated.

Upvotes: 4

Related Questions