Copy value into consts for optimization - c++

Assume that your first objective is execution speed, then code cleanliness and finally usage of resources.
If at a certain point of an algorithm a variable (for instance a double) is not going to change any more (but you are still going to read it many times), would you copy it into a constant value?

If you want to make your code clearer, by all means, copy your values into a const double const_value = calculated_value;, but compilers are very good at tracking dependencies, and it's highly unlikely (assuming you are using a modern, reasonably competent compiler) that the code will be any faster or otherwise "better" because you do this. There is a small chance that the compiler takes your word for the fact that you want a second variable, and thus makes a copy, and makes the code slower because of that.
As always, if performance is important to your application, make a "before & after" comparative benchmark for your particular code, as reading a page on the internet or asking on SO is not the same as benchmarking your code.

Just copying non-constant variable into a constant one does not make the code cleaner because instead of one variable you have two. Much more interesting would be to move non-constant one out-of-scope. This way, we have only constant version of the variable visible and compiler prevents us from changing its value by mistake.
Herb Sutter describes how to do this using C++11 lambdas: Complex initialization for a const variable.
const int i = [&]{
int i = some_default_value;
if(someConditionIstrue)
{
Do some operations and calculate the value of i;
i = some calculated value;
}
return i;
} ();
(I don't explain execution speed objective since it is already done by Mats Petersson).

For better code readability, you can create a const reference to the variable at the point where it isn't changed anymore, and use the const reference from that point on.
double value_init;
// Some code that generates value_init...
const double& value = value_init;
// Use value from now on in your algorithm

Related

Function calls vs. local variables

I often see functions where other functions are called multiple times instead of storing the result of the function once.
i.e (1):
void ExampleFunction()
{
if (TestFunction() > x || TestFunction() < y || TestFunction() == z)
{
a = TestFunction();
return;
}
b = TestFunction();
}
Instead I would write it that way, (2):
void ExampleFunction()
{
int test = TestFunction();
if (test > x || test < y || test == z)
{
a = test;
return;
}
b = test;
}
I think version 2 is much better to read and better to debug.
But I'm wondering why people do it like in number 1?
Is there anything I don't see? Performance Issue?
When I look at it, I see in the worst case 4 function calls in number (1) instead of 1 function call in number (2), so performance should be worse in number (1), shouldn't it?
I'd use (2) if I wanted to emphasize that the same value is used throughout the code, or if I wanted to emphasize that the type of that value is int. Emphasizing things that are true but not obvious can assist readers to understand the code quickly.
I'd use (1) if I didn't want to emphasize either of those things, especially if they weren't true, or if the number of times that TestFunction() is called is important due to side-effects.
Obviously if you emphasize something that's currently true, but then in future TestFunction() changes and it becomes false, then you have a bug. So I'd also want either to have control of TestFunction() myself, or to have some confidence in the author's plans for future compatibility. Often that confidence is easy: if TestFunction() returns the number of CPUs then you're happy to take a snapshot of the value, and you're also reasonably happy to store it in an int regardless of what type it actually returns. You have to have minimal confidence in future compatibility to use a function at all, e.g. be confident that it won't in future return the number of keyboards. But different people sometimes have different ideas what's a "breaking change", especially when the interface isn't documented precisely. So the repeated calls to TestFunction() might sometimes be a kind of defensive programming.
When a temporary is used to store the result of a very simple expression like this one, it can be argued that the temporary introduces unecessary noise that should be eliminated.
In his book "Refactoring: Improving the Design of Existing Code", Martin Fowler lists this elimination of temporaries as a possibly beneficial refactoring (Inline temp).
Whether or not this is a good idea depends on many aspects:
Does the temporary provides more information than the original expression, for example through a meaningful name?
Is performance important? As you noted, the second version without temporary might be more efficient (most compilers should be able to optimize such code so that the function is called only once, assuming it is free of side-effects).
Is the temporary modified later in the function? (If not, it should probably be const)
etc.
In the end, the choice to introduce or remove such temporary is a decision that should be made on a case by case basis. If it makes the code more readable, leave it. If it is just noise, remove it. In your particular example, I would say that the temporary does not add much, but this is hard to tell without knowing the real names used in your actual code, and you may feel otherwise.
The second option is clearly superior.
You want to emphasize and ensure that you have three times the same value in the if-statement.
Performance should not be a bottleneck in this example. In conclusion minimizing the chance for errors plus emphasize same values are much more important then a potential small performance gain.
The two are not equivalent. Take for example:
int TestFunction()
{
static int x;
return x++;
}
In a sane world though, this wouldn't be the case, and I agree that the second version is better. :)
If the function, for some reason, can't be inlined, the second will even be more efficient.
I think version 2 is much better to read and better to debug.
Agreed.
so performance should be worse in number (1), shouldn't it?
Not necessarily. If TestFunction is small enough, then the compiler may decide to optimize the multiple calls away. In other cases, whether performance matters depends on how often ExampleFunction is called. If not often, then optimize for maintainability.
Also, TestFunction may have side-effects, but in that case, the code or comments should make that clear in some way.

Returning a Static Local Reference

Suppose I have a function that will return a large data structure, with the intention that the caller will immediately copy the return value:
Large large()
{
return Large();
}
Now suppose I do not want to rely on any kind of compiler optimizations such as return value optimization etc. Also suppose that I cannot rely on the C++11 move constructor. I would like to gather some opinions on the "correctness" of the following code:
const Large& large()
{
static Large large;
large = Large();
return large;
}
It should work as intended, but is it poor style to return a reference to a static local even if it is const qualified?
It all depends on what should work as expected means. In this case all callers will share references to the exact same variable. Also note that if callers will copy, then you are effectively disabling RVO (Return Value Optimization), which will work in all current compilers [*].
I would stay away from that approach as much as possible, it is not idiomatic and will probably cause confusion in many cases.
[*]The calling convention in all compilers I know of determines that a function that returns a large (i.e. does not fit a register) variable receives a hidden pointer to the location in which the caller has allocated the space for the variable. That is, the optization is forced by the calling convention.
I don't think there's any issue with doing this. So long as this code base is, and forever will be, single threaded.
Do this on a multithreaded piece of code, and you might never be able to figure out why your data are occasionally being randomly corrupted.

Can adding 'const' to a pointer help the optimization?

I have a pointer int* p, and do some operations in a loop. I do not modify the memory, just read. If I add const to the pointer (both cases, const int* p, and int* const p), can it help a compiler to optimize the code?
I know other merits of const, like safety or self-documentation, I ask about this particular case. Rephrasing the question: can const give the compiler any useful (for optimization) information, ever?
While this is obviously specific to the implementation, it is hard to see how changing a pointer from int* to int const* could ever provide any additional information that the compiler would not otherwise have known.
In both cases, the value pointed to can change during the execution of the loop.
Therefore it probably will not help the compiler optimize the code.
No. Using const like that will not provide the compiler with any information that can be used for optimization.
Theoretically, for it to be a help to your compiler, the optimizer must be able to prove that nobody will ever use const_cast on your const pointer yet be unable to otherwise prove that the variable is never written to. Such a situation is highly unlikely.
Herb Sutter covers this is more depth in one of his Guru of the Week columns.
It can help or it can make no difference or it can make it worse. The only way to know is to try both and inspect the emitted machine code.
Modern compilers are very smart so they can often deduce that memory is unchanged without any qualifiers (pr they can deduce many other optimizations are possible without code being written in manner easier to analyze) yet they are rather complex and so have a lot of deficiencies and often can't optimize every possible thing at every opportunity.
I think the compiler can't do much in your scenario. The fact that your pointer declared as const int * const p doesn't guarantee that the memory can't be changed externally, e.g. by another thread. Therefore the compiler must generate code that reads the memory value on each iteration of your loop.
But if you are not going to write to the memory location and you know that no other piece of code will, then you can create a local variable and use it similar to this:
const int * p = ...
...
int val = *p;
/* use the value in a loop */
for (i = 0; i < BAZILLION; i++)
{
use_value(val);
}
Not only you help potential readers of your code to see that the val is not changed in a loop, but you also give the compiler a possibility to optimize (load val in a register, for instance).
Using const is, as everyone else has said, unlikely to help the compiler optimize your loop.
It may, however, help optimise code outside the loop, or at the site of a call to a const-qualified method, or to a function taking const arguments.
This is likely to depend on whether the compiler can prove it's allowed to eliminate redundant loads, move them around, or cache calculated values rather than re-calculating them.
The only way to prove this is still to profile and/or check the assembly, but that's where you should probably be looking.
You don't say which compiler you are using. But if you are both reading and writing to memory you could benefit from using "restrict" or similar. The compiler does not know if your pointers are aliasing the same memory so any store often forces loading other values again. "restrict" tells the compiler that no aliasing of the pointer is happening and can keep using values loaded before a subsequent write. Another way to avoid the aliasing issue is to load your values into local variables then the compiler is not forced to reload after a write.

variables as opposed to class calls

I have recently learned that if you have a reference to a class as a function parameter, it is better practice and more efficient to store certain needed pieces of information as local variables rather than accessing the classes members every time you need them in the function.
so...
void function(const Sphere& s)
{
//lots of calls to s.centre and s.radius
}
or
void function(const Sphere& s)
{
Vector3 centre = s.centre; float radius = s.radius;
//an equal amount of calls to centre and radius
}
I am told the second is better, but why? And also, where is a good place to start researching this more fully? (for dummys please!)
Whoever told you this probably thought that the second version was likely to be faster.
I think this is bad advice, for two reasons:
It may or may not actually be faster. This depends on the compiler, on what exactly the code is doing etc.
Even if it is faster, this screams premature optimization. One should micro-optimize only after profiling the code and establishing which part of the code is the overall bottleneck.
The concept is intuitive, but wrong. The concept is that accessing members takes more calculations than local variables, so by converting members to variables, you save performance.
But this is wrong. Your compiler will optimize this in ways you could never imagine. Don't attempt to be smarter than the compiler.
This could actively be dangerous. If s.centre or s.radius change during the execution of this function (say due to a function you call or another thread), you will end up with two inconsistent, old values in your local variables -- causing bugs. Even if you're doing this safely, why take the chances of introducing bugs when you can just refer back to the canonical variables themselves?
You were lied to. Moreover, you should not be worrying about such minutiae unless you have profiled your code and found this to be a main source of inefficiency in your code. Don't try to outsmart your compiler's optimizer. It is better at optimizing your code than you are.
Here is a general outlook of your code:
void function(Sphere s)
{
Vector3 centre = s.centre; float radius = s.radius;
//an equal amount of calls to centre and radius
}
First off, you'd gain much more efficiency by passing Sphere as a const reference. This way, a new copy isn't created, which is probably more expensive than member access. So the way to go is:
void function(const Sphere& s)
{
Vector3 centre = s.centre; float radius = s.radius;
//an equal amount of calls to centre and radius
}
Secondly, you shouldn't access members of classes directly. It may be easy now, but in a large project it's really hard to debug. You should use inline getters and setters. That way, the generated code is the same, but you have a single entry point.
Thirdly, this version isn't thread safe. What if a different thread changes s? s.center and s.radius would change, but you'd still be operating on the old values.
Lastly, compilers do a better job at optimizing than you can, so it's better to leave this one up to the compiler.
Whoever told you that is wrong. You can improve performance by using inline functions. Also in your example use
void function(Sphere &s)
Saves using the copy constructor.

Efficiency of explicit initialization

I have a class which has a constructor that takes a const char*. It is:
c::c(const char* str) {
a = 32;
f = 0;
data = new char[strlen(str)];
memcpy(data, str, strlen(str));
}
And a function which takes one of them:
int foo(c& cinst);
You can call this function either by passing it an instance of a c:
c cinst("asdf");
foo(cinst);
or, because we have explicit initialization, you can do:
foo("asdf");
which will make a c by passing the constructor "asdf" and then pass the resulting object to foo.
However, this seems like it might be quite a bit less efficient than just overloading foo to take a const char*. Is it worth doing the overload for the speed or is the performance impact so small that it's a waste of space to make an overload? I'm trying to make my program as fast as possible, so speed is an important factor, so is size, but not so much.
What will foo be doing with that const char*? If it's just going to make it own c object, then there's no point.
If it is going to use the char* directly (and the existing foo just pulled the char* out of the c object), then it would be better to write an overload.
It won't take zero time so it is one of the tradeoffs you have to take, speed versus api clarity. Of course it will depend on what you are doing in your function that takes a const char*, are you constructing a c object? In which case just offer the function with the c class interface.
This sort of question is best answered with a profiler.
Looking at the assembler code for it may also provide a clue.
It's situational. It really depends on just how much is really going on inside a constructor in a given situation and how many times that code is actually being executed.
In the example you give, those are pretty trivial operations in that constructor. On any reasonable modern processor those operations are going to be very very quick. So unless that code is being executed a huge number of times per second or more, then I wouldn't even worry about it. (Of course the value of "huge" depends on what kind of machine you expect to run this on. For this constructor, on a typical desktop processor, I wouldn't even begin to worry until it gets up into the scale of at least hundreds-of-thousands of times per second.)
If this construction code does run some huge number of times, then you still ought to profile it and determine for sure if it's having a noticeable impact compared to everything else going on in your program. Optimization is a tricky thing. Sometimes what your gut feeling says is inefficient actually has little impact on the end results. Measurement is always to way to determine where you should actually be spending your time to most effectively make your program run faster.