8

How long does it take to declare a variable in C, for example int x or unsigned long long var? I am wondering if it would make my code any faster in something like this.

for (conditions) {
    int var = 0;
    // code
}

Would it be faster to do this, or is it easier not to?

int var;
for (conditions) {
    var = 0;
    // code
}

Thanks for the help.

Michael Dickens
  • 1,454
  • 4
  • 18
  • 26
  • 2
    @tne - This question was asked 4 years ago and the one you linked was asked 10 months ago. If anything, the other should be closed as a duplicate of this. – beatgammit Feb 24 '14 at 05:38

12 Answers12

13

One piece of advice: stop worrying about which language constructs are microscopically faster or slower than which others, and instead focus on which ones let you express yourself best.

Also, to find out where your code is spending time, use a profiler.

And as others have pointed out, declarations are purely compile-time things, they don't affect execution time.

Ned Batchelder
  • 364,293
  • 75
  • 561
  • 662
13

It doesn't make any difference. In a traditional implementation the declaration itself (excluding initialization) generates no machine instructions. Function prologue code typically allocates space in the stack for all local variables at once, regardless of where they are declared.

However, where you declare your local variables can affect the performance of your code indirectly, in theory at least. When you declare the variables as locally as possible (your first variant), in general case it results in smaller size of the stack frame reserved by the function for its local variables (since the same location in the stack can be shared by different local variables at different times). Having smaller stack frame reduces the general stack memory consumption, i.e. as nested function calls are performed stack size doesn't grow as fast (especially noticeable with recursive functions). It generally improves performance since new stack page allocations happen less often, and stack memory locality becomes better.

The latter considerations are platform-dependent, of course. It might have very little or no effect on your platform and/or for your applications.

AnT stands with Russia
  • 312,472
  • 42
  • 525
  • 765
  • 1
    Unless the variable's address is taken, the location of the declaration should not affect the size of the stack frame either. Any decent optimizing compiler will see that the variable is only used in one block. – Jason Orendorff Dec 29 '09 at 16:18
10

Whenever you have a question about performance, the best thing to do is wrap a loop around it (millions of iterations) and time it. But, in this case, you will likely find that it makes no difference.

It is more important to properly express the intentions of your code. If you need the variable outside your loop, delare it outside. If you only need the variable inside the loop, declare it inside.

You should always declare and initialize variables in narrowest scope possible.

You shouldn't be worrying about those types of micro-optimizations anyway (except in the rarest, rarest of cases). If you really need to worry about potential nano-second performance improvements, measure the difference. It is very unlikely that your variable declarations will be the largest bottleneck in your application.

Robert Cartaino
  • 27,494
  • 6
  • 45
  • 67
  • 1
    If your working on some C code for an embedded chip this kind of thing is in micro seconds rather than nano-seconds and can be quite important (depending on your chip, application, etc.). If you are writing such code then knowing that declaring variables outside the for loop should guarantee they only get allocated once can be quite important. By declaring the variable inside the loop the compiler may choose to allocate it many times over and clean it up at the end of the loop too which will be much slower. – TafT Aug 16 '11 at 12:00
  • 1
    Out of everyone here saying that it doesn't matter, @TafT is one of the few with the right idea. You should always have at least a rough idea of what the compiler is going to do for a given snippet of code. You shouldn't fret over every little decision, but you also shouldn't sling code however you please with the expectation that the compiler will magically make everything awesome. The compiler is merely a tool, and you should be aware of its capabilities and limitations. –  Mar 15 '18 at 21:02
5

It takes no time at all. The memory for global variables is allocated at startup, and "declaring" variables on the stack simply involves how far "up" the stack pointer moves when the function is called.

rlbond
  • 65,341
  • 56
  • 178
  • 228
  • There is nothing to suggest that the `int var` in the question is a global variable. Some simple compilers will allocate memory for every variable at compile time (no dynamic memory) but others could/would allocate when the braces `{` that wrap `int var` are entered and allocated it when they are `}` exited. – TafT Mar 19 '18 at 15:56
4

declarations are purely compile time, they cost nothing at runtime¹. But the first piece of code is still better than the second for two reasons

  • you should always initialize variables when you declare them, they way they can never have uninitialized values. This goes hand in hand with
  • always use the narrowest possible scope for variable declarations

So your first example, while no faster than the second, is still better.

And all of the people who chimed in telling him not to prematurely or micro optimize his code are wrong. It is never bad to know how costly various bits of code are. The very best programmers have a solid, almost unconcious, grasp of the cost of various strategies and take that into account automatically when they design. The way you become that programmer is to ask just this sort of question when you are a beginner.

¹ In fact, there is a small cost when each function allocates space for local variables, but that cost is the same regardless of how many local variables there are*.

*ok that's not really true, but the cost depends only on the total amount of space, not the number of variables.

PerfTLL
  • 3
  • 2
John Knoeller
  • 33,512
  • 4
  • 61
  • 92
  • +1 for 'It is never bad to know how costly various bits of code are.' – int3 Dec 24 '09 at 18:42
  • Another +1 for 'It is never bad to know how costly various bits of code are.' – Jason Orendorff Dec 29 '09 at 15:56
  • There's a pending edit on this answer with one accept and one reject currently. I've left it as because it significantly changes the meaning of the answer - I think you're probably the most appropriate person to approve or reject it. – Flexo Sep 15 '11 at 09:37
3

Declaration takes no time at all.

The compiler will interpret that line as a notification that space for it will need to exist on the stack.

Drew Dormann
  • 59,987
  • 13
  • 123
  • 180
  • Well, it does take *some* time, you need to move the stack pointer. But it's negligible. – paxdiablo Dec 24 '09 at 02:44
  • 2
    ...and the compiler will almost certainly hoist the stack push out of the loop -- i.e., the work will (probably) be the same (negligible) whether it's declared outside or inside the loop. – mrkj Dec 24 '09 at 03:02
  • 1
    @paxdiablo: I don't think that's right, but follow my logic and anyone's welcome to tell me if I'm wrong: Declaring a variable won't increment the stack pointer at all. That variable will just be *some offset* from the SP. When another function is called, the SP will increment regardless. The declaration of an `int` on the stack only *potentially affects* how much the SP is adjusted. – Drew Dormann Dec 24 '09 at 03:07
  • 2
    This is C, not C++: variables are not constructed. – dave4420 Dec 24 '09 at 03:23
  • 1
    @Shmoopty: after playing around with gcc a bit more, I'm pretty sure you're right. – mrkj Dec 24 '09 at 03:34
  • 1
    @Shmoopty, I believe you are correct. – Matt Joiner Dec 24 '09 at 03:41
  • @Shmoopty, while it's not mandated by the standards, @mrkj is probably right. Any compiler writer worth their salt would almost certainly fold all possible stack movements into the one at the start of the function and then just use the offset within a block. – paxdiablo Dec 24 '09 at 04:16
1

I wouldn't care about a nanosecond here or there. Unless you need to access its value after the for loop ends, leave the variable inside the loop: it will be closer to the code that uses it (your code will be more readable), and its scope will be bounded by the loop itself (your code will be more elegant and less bug-prone).

Federico A. Ramponi
  • 46,145
  • 29
  • 109
  • 133
1

As others have already said, it shouldn't take any time. Therefore you need to make this decision based on other factors: what would make your code more readable and less prone to bugs. It's generally considered a good practice to declare a variable as close as possible to its usage (so you can see the declaration and usage in one go). If it's only used in the inner scope then just declare it inside that scope - forget about performance on this one.

EMP
  • 59,148
  • 53
  • 164
  • 220
1

Declaring variables does take time, as it results in machine language instructions that allocate the space for the variables on the stack. This is simply an increment of the stack pointer, which takes a tiny, but non-zero amount of time.

I believe your question is whether more time will be required (i.e. more stack increment operations) if the variable is declared inside the loop. The answer is no, since the stack is incremented once only for the loop block, not each time the loop is executed. So, there will be no difference in time either way, even if the loop executes zillions of zillions of times.

Larry Watanabe
  • 10,126
  • 9
  • 43
  • 46
1

Disclaimer: Precisely what happens depends on your compiler, architecture, etc. But conceptually here's what's going on:

When you declare a variable within a method, it is allocated on the stack. Allocating something on the stack only involves bumping up the stack pointer by the size of the variable. So, for example, if SP represents the memory address of the top of the stack, declaring char x results in SP += 1 and int x results in SP += 4 (on a 32 bit machine).

When the function exits, the stack pointer is returned to where it was before your method was called. So deallocating everything is fast, too.

So, either way it's just an add, which takes the same amount of time regardless of the amount of data.

A smart compiler will combine several variable declarations into a single add.

When you declare a variable within a loop, in theory it could be changing the stack pointer on each iteration through the loop, but again, a smart compiler probably won't do that.

(A notable exception is C++, which does extra work because it needs to call constructors and destructors when the stack-allocated object is created or destroyed.)

benzado
  • 82,288
  • 22
  • 110
  • 138
1

I bet the compiled binary will be identical for both cases.

Nicolás
  • 7,423
  • 33
  • 35
  • This might be the best answer. In fact it's the only one that doesn't strike me as misleading. For an explanation of how and why a compiler might ignore the location of the declaration, see "static single assignment form". http://en.wikipedia.org/wiki/Static_single_assignment_form – Jason Orendorff Dec 29 '09 at 16:12
0

Variable declaration is turned into stack space reservation by the compiler. Now how does this work is entirely platform-dependent. On x86 and pretty much every popular architecture this is just a subtraction from the address of the stack frame and\or indexing addressing mode to access from the top of the stack. All these come with the cost of a simple subtraction\addition, which is really irrelevant.

Technically the second example is less efficient, because the declaration happens on every entry into the loop scope, i.e. on every loop iteration. However it is 99.99% chance that the stack space will be reserved only once.Even the assignment operation will be optimized away, although technically it should be done every loop iteration. Now in C++ this can get much worse, if the variable has a constructor which will then be run on every loop iteration.

And as a bottom line, you really should not worry about any of such issues without proper profiling. And even then there are much more valuable questions to ask yourself here, like "what is the most readable way to do this, what is easier to understand and maintain, etc.".

Inso Reiges
  • 1,889
  • 3
  • 17
  • 30