views:

115

answers:

5

I've got a code that as you can see I can write in either of two following ways, the matter is the only difference is since in second function the parameter is declared as non-constant I can use that instead of declaring a new variable(num1 in first function) but I' curious which one would be more suited if there would be any difference between output assembly codes generated by compiler for each one:

void Test(const long double input){
 long double num=(6.0*input);
 long double num1=9.0;
 for (int i=0;i<5;i++)
  num1*=num;
 cout <<num1<<'\n';
}

void Test(long double input){
 long double num=(6.0*input);
 input=9.0;
 for (int i=0;i<5;i++)
  input*=num;
 cout <<input<<'\n';
}
+3  A: 

A good optimizing compiler could theoretically make them equivalent (i.e., generate equivalent code for both) via enregistration into floating point registers of the numbers, although this may not result in the fastest code. Whether such a compiler exists is a good question.

For stylistic (i.e., readability) reasons, though, I prefer the first, so that the same variable does not get used for two different things:

void Test(const long double input){ 
 long double num=(6.0*input); 
 long double num1=9.0; 
 for (int i=0;i<5;i++) 
  num1*=num; 
 cout <<num1<<'\n'; 
}
Michael Goldshteyn
2nd'd. But don't forget that const-ness for primitive types does degrade to the same signature when it comes to overload resolution.
gimpf
+1  A: 

What the compiler generates is entirely dependent on your compiler flags and platform. It would be an interesting exercise to generate the assembler outputs for each of the above using full optimization (just give them diff function names) and post it here for definitive comment, or as a separate question).

My guess is that you are most likely concerned about performance - if so, I would just write a small wrapper app to call each function N times and then output the relative timings, possibly excluding the cout part to avoid console I/O skewing the results.

Steve Townsend
A: 

Well in the second function you're reusing stack space from the argument, while in the first function the compiler has to reserve space for num1. The assembly instructions should be the same, save for the addresses/offsets used.

DarkDust
@DarkDust - for a small function like this, many compilers on mainstream multi-register CPUs will not need stack space to get this work done.
Steve Townsend
When it comes to optimization, you can assume nothing except for the same external behavior as defined by the standard. Plus, the bugs.
gimpf
+1  A: 

Like this:

void Test(long double input)
{
    long double factor = 6.0 * input;
    long double result = 9.0;

    for (int i = 0; i < 5; ++i)
        result *= factor;

    cout << result << '\n';
}

Note we put spaces between things for the same reason weputspacesbetweenwords and give things meaningful names, so it's actually readable...

GMan
+1  A: 

Like this:

void Test(long double input)
{
    long double const factor = 6.0 * input;
    long double       result = 9.0 * pow(factor, 5);

    cout << result << '\n';
}

If you must use the loop then I would follow GMan's example.

One variable for one use. Trying to re-use variables has no meaning. The compiler does not even have the concept of variable names. It re-uses slots when appropriate (notice I use the term slot: it multiple variables can use the same slot).

The compiler is just so much better at optimization than a human that it is counter productive to try and beat it (use better algorithms this is were the human factor comes in because the compiler does not understand algorithms).

The biggest thing about code is not writing it but maintaining it. So your code MUST be written to be easy to maintain for the next person (a company will spend much more on maintenance then developing new code). The old adage is write your code knowing that the maintainer is an axe murder that knows where you live.

Martin York