Assuming buffer is a struct composed of several members, including an array.
Compiling with usual optimization flags, what kind of performance difference should one expect from running these two code snippets ?
buffer buf;
for (int i = 0; i < BIG_ENOUGH_NUMBER; i++) {
init(huge_file, i, &buf);
}
// buf is not used afterward
...
void init(FILE* f, int i, buffer* b) {
... // b is filled using f, according to i
do_something(b);
}
vs
for (int i = 0; i < BIG_ENOUGH_NUMBER; i++) {
init(huge_file, i);
}
...
void init(FILE* f, int i) {
buffer buf;
... // buf is filled from scratch using f, according to i
do_something(&buf);
}
The first answer is: benchmark them.
A second answer is: compile them to assembly language, and look at the source. Doing this with and without optimsation flags could be instructive.
As pointed out be abelenky, in both cases
bufis on the stack. My general guess is that the second case would be slightly faster (with compilers I’ve used), because buf does not have to be passed on as an argument. It does have to be allocated on the stack, but stack allocation is typically just a slightly different size of the function’s call frame. The same amount of work has to be done (adjusting the stack pointer) regardless of how big that frame is.So I’d expect the main difference in generated code would be one fewer “PUSH” instructions in the second case, assuming that there are enough arguments that some will have to go on the stack. (If they’re all in registers, that’s a bit different.)
It may be affected by optimisation, for instance whether
bufends up in a register in each case. But the missing code to populate buf could affect this so I won’t speculate.Note that the above is my guess based on looking at the behaviour of my compiler. In theory, compilers can translate code however they like as long as the resulting program runs correctly, which makes it hard to generalise about what optimisations they may or may not do.